Hello guys sorry to bother again with a horrible question
I have the following mdx and I need to format the date YYYYMMDD but I am having trouble as no matter how I phrase it it wont compile on the store procedure, or if it does the resulting mdx is no good.
Heres the code I have so far, using sqlserver 2000.
set #CONSULTA = 'select [' +CONVERT(VARCHAR(8), #fecha, 112)+ '] AS [' +YYYYMMDD+ '], A.*
from (SELECT
isnull(CAST("[Measures].[Cajas Dia]" As float(18,6)),2) As cajas_dia,
isnull(CAST("[Measures].[P Redondeadas]" As int),2) As pz_redondeo
FROM openrowset(''MSOLAP'',''DATASOURCE=XXXX; Initial Catalog=XXXX; User Id=XXX;Password=XXX;'', '+ '''' + #MDX +''''+')) as A
'
I think you'd want to use style 112 instead of 122 on the CONVERT. Also not sure why you have square brackets around that in your query.
CONVERT(VARCHAR(8), #fecha, 112)
Is this what you need?
There is no style 122 and I assume you are trying to bring the date back as a literal and alias that column as YYYYMMDD?
set #CONSULTA = 'select ''' +CONVERT(VARCHAR(8), #fecha, 112)+ ''' AS [YYYYMMDD], A.*
from (SELECT
isnull(CAST("[Measures].[Cajas Dia]" As float(18,6)),2) As cajas_dia,
isnull(CAST("[Measures].[P Redondeadas]" As int),2) As pz_redondeo
FROM openrowset(''MSOLAP'',''DATASOURCE=XXXX; Initial Catalog=OLAP_HDZ; User Id=XXX;Password=XXX;'', '+ '''' + #MDX +''''+')) as A'
Related
Is there a way to get a count of distinct values from every table and column in SQL Server.
I've tried using a cursor for this, but that seems insufficient.
I've got to agree with Sean and say that this is going to be horrifically slow, but if you really want to do it, then I'm not going to stop you.
Something like this could be used as a starting point if you specifically don't want to use a cursor. This took just under a minute to look at a small database I've got with 10 tables in it. The largest table has just a few million rows in it. No matter what, you're going to be doing some sort of iteration, whether that's a cursor or explicitly reading against the table for each column.
Also, if you want to do something like this, you'll likely need to accommodate for things... like you're not going to be able to use COUNT on xml columns. Like I said, it's a starting point.
DECLARE #cmd VARCHAR(MAX)
SELECT #cmd =
STUFF (
(
SELECT
' union SELECT ''['+ SCHEMA_NAME(st.schema_id) + '].[' + st.name +']'' as [Object], ''[' + sc.name + ']'' as [Column], COUNT(distinct [' + sc.name + ']) as [Count] FROM [' + SCHEMA_NAME(st.schema_id) + '].[' + st.name + ']'
FROM sys.tables st
JOIN sys.columns sc
ON sc.object_id = st.object_id
JOIN sys.dm_db_partition_stats ddps
ON ddps.object_id = sc.object_id
WHERE
ddps.row_count > 0
FOR XML PATH('')
),1,6,''
)
EXECUTE (#cmd)
I have this Openrowset Query where I'm able to pass a Path to get the correct Excel file. I can't figure out the exact number of quotes and/or the type conversion
I need to pass a WHERE statement to get a specific date in the table. I'm coming from VBA where you put 2 quotes and 2 & and you're all set. It seems SQL needs hundreds of them! (If someone has a link to an online university about SQL quotes that'd be much appreciated too)
set #sql1 = 'select *
FROM OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',
''Excel 12.0;Database=' + #filePath1 + '' + ';' + '''' + ',
''Select * from [Sheet1$] '''+')'
exec(#sql1)
I'd like to add WHERE DATE = #PnLDate
The rule is very similar to what you know but it applies to single quote '. When you want one of them inside a string you escape it using two ''. Apart of them, you must have one for openning and one for closing.
The string you show, is a bit complicated just because it contains innecesary empty strings, and secuentialy contatenated stirngs that can be replaced just for only one resultant string. Below a simiplificated version of your string:
set #sql1 = 'select *
FROM OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',
''Excel 12.0;Database=' + #filePath1 + ';'',
''Select * from [Sheet1$] '')'
With your requested where may be:
DECLARE #PnLDate datetime -- may be varchar instead, if so, must remove convert(....) and use straight #PnLDate
set #PnLDate = '2014/08/01'
set #sql1 = 'select *
FROM OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',
''Excel 12.0;Database=' + #filePath1 + ';'',
''Select * from [Sheet1$] where DATE = #'+ -- hash # is MS Access delimiter for dates
convert(varchar(25), #PnLDate, 111)
+'#'')' -- results in #2014/08/01#
Be warned that when you use "dynamic SQL" your data can inject malicious code on the string. read about sql Injection
I have this portion of the query where I'm doing this.
FROM #Table2 WHERE Attribute = ISNULL('+#Attrb+', Attribute)) AS D
Obviously this isn't working for me as #Attr can bring in a string or can be empty. is there a better way to handle this?
What I need is, this a parameter that is passed to this stored procedure. There are two possible choices (or a third one is empty). I'm allowing the users to type it in. How would you tackle this?
Thanks.
FROM #Table2 ' + ISNULL('WHERE Attribute = ''' + NULLIF(#Attrb,'') + '''', '') + ') AS D
Example
CREATE TABLE #Table2 (Attribute VARCHAR(MAX))
INSERT INTO #Table2 VALUES
('Id'),('Class'),('Name')
DECLARE #Attrb VARCHAR(MAX),
#SQL VARCHAR(MAX)
--Attrb is NULL
SET #SQL = ' SELECT * FROM #Table2 ' + ISNULL('WHERE Attribute = ''' + NULLIF(#Attrb,'') + '''', '')
EXEC(#SQL)
/*Result
Attribute
---------
Id
Class
Name
*/
--Give Attrb a value
SET #Attrb = 'Class'
SET #SQL = ' SELECT * FROM #Table2 ' + ISNULL('WHERE Attribute = ''' + NULLIF(#Attrb,'') + '''', '')
EXEC(#SQL)
/*Result
Attribute
---------
Class
*/
You haven't indicated what version of SQL server you are using, but if you are using 2012 or later, you might want to check iif
Example for testing:
declare #Attrib varchar(20)
set #Attrib = NULL
select iif(#Attrib is null,'Null Result',#Attrib)
I am not sure what the string literals are doing in there. I am pretty sure you want something like this.
WHERE Attribute = ISNULL(#Attrb, Attribute)
Or if you are trying to deal with NULL or an empty string you can use NULLIF
WHERE Attribute = ISNULL(NULLIF(#Attrb, ''), Attribute)
--EDIT--
Modifying this to work with dynamic sql is pretty straight forward.
'WHERE Attribute = ISNULL(NULLIF(' + ISNULL(#Attrb, Attribute) + ', ''''), Attribute)'
Please look at the below query..
select name as [Employee Name] from table name.
I want to generate [Employee Name] dynamically based on other column value.
Here is the sample table
s_dt dt01 dt02 dt03
2015-10-26
I want dt01 value to display as column name 26 and dt02 column value will be 26+1=27
I'm not sure if I understood you correctly. If I'am going into the wrong direction, please add comments to your question to make it more precise.
If you really want to create columns per sql you could try a variation of this script:
DECLARE #name NVARCHAR(MAX) = 'somename'
DECLARE #sql NVARCHAR(MAX) = 'ALTER TABLE aps.tbl_Fabrikkalender ADD '+#name+' nvarchar(10) NULL'
EXEC sys.sp_executesql #sql;
To retrieve the column name from another query insert the following between the above declares and fill the placeholders as needed:
SELECT #name = <some colum> FROM <some table> WHERE <some condition>
You would need to dynamically build the SQL as a string then execute it. Something like this...
DECLARE #s_dt INT
DECLARE #query NVARCHAR(MAX)
SET #s_dt = (SELECT DATEPART(dd, s_dt) FROM TableName WHERE 1 = 1)
SET #query = 'SELECT s_dt'
+ ', NULL as dt' + RIGHT('0' + CAST(#s_dt as VARCHAR), 2)
+ ', NULL as dt' + RIGHT('0' + CAST((#s_dt + 1) as VARCHAR), 2)
+ ', NULL as dt' + RIGHT('0' + CAST((#s_dt + 2) as VARCHAR), 2)
+ ', NULL as dt' + RIGHT('0' + CAST((#s_dt + 3) as VARCHAR), 2)
+ ' FROM TableName WHERE 1 = 1)
EXECUTE(#query)
You will need to replace WHERE 1 = 1 in two places above to select your data, also change TableName to the name of your table and it currently puts NULL as the dynamic column data, you probably want something else there.
To explain what it is doing:
SET #s_dt is selecting the date value from your table and returning only the day part as an INT.
SET #query is dynamically building your SELECT statement based on the day part (#s_dt).
Each line is taking #s_dt, adding 0, 1, 2, 3 etc, casting as VARCHAR, adding '0' to the left (so that it is at least 2 chars in length) then taking the right two chars (the '0' and RIGHT operation just ensure anything under 10 have a leading '0').
It is possible to do this using dynamic SQL, however I would also consider looking at the pivot operators to see if they can achieve what you are after a lot more efficiently.
https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
CREATE PROCEDURE [dbo].[sp_SelectRecipientsList4Test] --'6DBF9A01-C88F-414D-8DD9-696749258CEF','Emirates.Description','0','5'
--'6DBF9A01-C88F-414D-8DD9-696749258CEF',
--'121f8b91-a441-4fbf-8a4f-563f53fcc103'
(
#p_CreatedBy UNIQUEIDENTIFIER,
#p_SortExpression NVARCHAR(100),
#p_StartIndex INT,
#p_MaxRows INT
)
AS
SET NOCOUNT ON;
IF LEN(#p_SortExpression) = 0
SET #p_SortExpression = 'Users.Name Asc'
DECLARE #sql NVARCHAR(4000)
SET #sql='
DECLARE #p_CreatedBy UNIQUEIDENTIFIER
SELECT
Name,
POBox,
EmirateName,
TelephoneNo,
RecipientID,
CreatedBy,
CreatedDate,
ID
FROM
(
SELECT Users.Name, Users.POBox, Emirates.Description As EmirateName,
UserDetails.TelephoneNo, AddressBook.RecipientID,AddressBook.CreatedBy, AddressBook.CreatedDate,
AddressBook.ID,
ROW_NUMBER() OVER(ORDER BY '+ #p_SortExpression +') AS Indexing
FROM AddressBook INNER JOIN
Users ON AddressBook.RecipientID = Users.ID INNER JOIN
UserDetails ON Users.ID = UserDetails.UserID INNER JOIN
Emirates ON Users.EmiratesID = Emirates.ID
----WHERE (AddressBook.CreatedBy = #p_CreatedBy)
) AS NewDataTable
WHERE Indexing > '+ CONVERT(NVARCHAR(10), #p_StartIndex) +
' AND Indexing<=(' + CONVERT (NVARCHAR(10),#p_StartIndex ) + ' + '
+ CONVERT(NVARCHAR(10),#p_MaxRows)+') '
EXEC sp_executesql #sql
This query is not giving any error but also not giving any result
please help
Have you tried breaking down the statement, to check if intermediate results are as expected? That's what you do to debug a complex statement...
For example, there's a nested SELECT in there. If you commit that SELECT on its own, does it print the expected values?
Edit: There's a saying about teaching a man to fish. 'ck' and 'n8wrl' have given you fish to eat today, now please practice fishing to feed you tomorrow...
Well, a quick glance of this:
WHERE Indexing > '+ CONVERT(NVARCHAR(10), #p_StartIndex) + ' AND Indexing<=(' + CONVERT (NVARCHAR(10),#p_StartIndex ) +...
looks like you're looking for an impossible condition, not unlike this:
WHERE Indexing > 5 AND Indexing <= 5
So that might be why you're getting no rows, but this proc is ripe for SQL injection attacks too. Building SQL on the fly based on possibly-unvalidated parameters is very dangerous.
You are querying:
'WHERE Indexing > '+ CONVERT(NVARCHAR(10), #p_StartIndex) +
' AND Indexing<=(' + CONVERT (NVARCHAR(10),#p_StartIndex ) + ' + '
and then adding max rows as a string, you can do this much more easily like so:
'WHERE Indexing > '+ CONVERT(NVARCHAR(10), #p_StartIndex) +
' AND Indexing <='+ CONVERT(NVARCHAR(10),#p_StartIndex + #p_MaxRows)
EDIT
The problem with your inner WHERE is that you are passing in the parameter, you need to do
'WHERE (AddressBook.CreatedBy = ''' + CAST(#p_CreatedBy AS CHAR(36)) + ''')'
Are you sure all your joins should be inner joins?
Change sp_executesql to PRINT and see what gets generated (the poor man's debugger)
Besides what all the other people told you,
give me one good reason why you are using sp_executesql over exec? You are not using parameterized statements, you also are not protected from sql injections because you just execute the whole string
This will just bloat the procedure cache everytime this is run and some values change, you will get a new plan every time
Please take a look at Changing exec to sp_executesql doesn't provide any benefit if you are not using parameters correctly and Avoid Conversions In Execution Plans By Using sp_executesql Instead of Exec