Passing a Scalar reference into another Scalar - sql-server-2008

In SQL Server, I have a stored procedure that accepts a date parameter. That date paramater is then passed along to another stored procedure. However, the 2nd stored procedure parameter is named as the first parameter. and then I need to I have 2 different scalar variables:
DECLARE #date date, #sql varchar(100);
SET #date = '2012-07-01';
SELECT #sql = ('EXEC pStoredprocedure #date = '''+#date+'''')
I need the #sql scalar to contain this text so the stored procedure can call the other stored procedure:
EXEC pStoredprocedure #date = '2012-07-01'
But, when I run my code above, I get this error:
Msg 402, Level 16, State 1, Line 4
The data types varchar and date are incompatible in the add operator.
It's almost like I need to escape the #date operator. Can this be done?
Side note: Yes, I'm trying to dynamically pass along some variables. I understand the dangers of doing so, but doing it this way is much simpler...

The date variable is being used in string concatenation, so it should be treated as a string, either through its declaration, a convert function, or a cast. I tried this:
DECLARE #date varchar(20), #sql varchar(100);
SET #date = '2012-07-01';
SELECT #sql = ('EXEC pStoredprocedure #date = ''' + #date + '''')
PRINT #sql
and got this:
EXEC pStoredprocedure #date = '2012-07-01'
I am stuck on 2005, so I don't have the date datatype, but when I tried to use datetime, I got this error:
Msg 241, Level 16, State 1, Line 4 Conversion failed when converting
datetime from character string.
You can also try
DECLARE #date datetime, #sql varchar(100);
SET #date = '2012-07-01';
SELECT #sql = ('EXEC pStoredprocedure #date = ''' + CONVERT(varchar(20), #date, 102) + '''')
PRINT #SQL;
and get
EXEC pStoredprocedure #date = '2012.07.01'

Related

Conversion failed when converting the nvarchar value '2151','1886' to data type int

I have the below query
DEClare #Plan_ID nvarchar(100)
set #Plan_ID=REPLACE('2151,1886',',',''',''')
and
SELECT distinct Plan_Dict_Id from REF_Plan_Dictionary WHERE
CAST(Plan_Dict_Id as int) in (#Plan_ID),
Pls help , Plan_Dict_Id datatype is INT, I want to pass the values to where , but getting error "Conversion failed when converting the varchar value '2151','1886' to data type int."
If this is one of the later versions of SQL Server then you could do something like this...
DECLARE #Plan_ID nvarchar(100)
SET #Plan_ID= '2151,1886'
SELECT DISTINCT Plan_Dict_Id
FROM REF_Plan_Dictionary d
JOIN string_split(#Plan_ID, ',') s ON d.Plan_Dict_Id = s.[value]
If you are using an older version you could put the whole statement in a string and then execute it, however you have a problem in your first line as you are not adding quotes around the string... I've accounted for that below.
DEClare #Plan_ID nvarchar(100) set #Plan_ID=REPLACE('2151,1886',',',''',''')
DECLARE #sql nvarchar(max)
SET #SQL = 'select distinct Plan_Dict_Id from REF_Plan_Dictionary where CAST(Plan_Dict_Id as int) in (''' + #Plan_ID + ''')'
EXEC (#sql)

SQL Asking To Declare Variable That Is Declared

I am attempting to run this SQL Syntax, but I keep getting an error of:
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#startDate".
However, it looks to me that the variable is already declared at the beginning of my procedure. Why is the error being thrown, and what do I need to do to fix it?
I am using this syntax to call my stored procedure:
exec [dbo].[DoThis] '01/01/2015','01/31/2015'
And this is full procedure which presents compile error above.
ALTER Procedure [dbo].[DoThis]
(
#startDate datetime,
#endDate datetime
)
As
Declare #storename varchar(500), #dblocation varchar(500), #sql varchar(max)
Select storename, dblocation
INTO #allstores
FROM tbl_allstores
where sales >= '1,000,000'
Declare c1 Cursor For
Select storename, dblocation
FROM #allstores
Open c1
Fetch Next From c1 Into #storename, #dblocation
While ##FETCH_STATUS = 0
Begin
Set #sql = 'Insert Into #storeinfo (storename, employeename, employeeaddress, employeephone) '
+'Select '''+#storename+''' As ''storename'', '
+'employeename, employeeaddress, employeephone '
+'From '+#dblocation+' '
+'where employeestatus = ''Active'' '
+'and CAST(hiredate As Date) BETWEEN CAST(#startDate As Date) AND CAST(#endDate As Date) '
Print(#sql)
exec(#sql)
Fetch Next From c1 Into #storename, #dblocation
End
Close c1
Deallocate c1
Select * from #storeinfo
Drop Table #allstores
Drop Table #storeinfo
When you exec(#sql) this creates a new context with its own local variables, and you have not passed the #startDate value into that context.
Instead, declare parameters for your SQL string like this:
exec sp_executesql #sql, '#startDate datetime, #endDate datetime',
#startDate, #endDate;
These names will now be available to your SQL, and the parameters will be passed to them.
This method is better because it treats the variables as parameters which is safer because it reduces the risk of SQL Injection.
As an additional tip, you should also pass #storeName as a parameter. As far as I know you cannot pass #dbname as a parameter, so you should instead ensure that it is quoted correctly.
So the full thing would be:
Set #sql = 'Insert Into #storeinfo (storename, employeename, employeeaddress, employeephone) '
+' Select #storename As ''storename'', '
+' employeename, employeeaddress, employeephone '
+' From '+QUOTENAME(#dblocation)+' '
+' where employeestatus = ''Active'' '
+' and CAST(hiredate As Date) '
+' BETWEEN CAST(#startDate As Date) AND CAST(#endDate As Date) '
Print(#sql)
exec sp_executesql #sql,
'#startDate datetime, #endDate datetime, #storeName nvarchar(100)',
#startDate, #endDate, #storeName;
Changing to:
+'and CAST(hiredate As Date) BETWEEN CAST(''' + #startDate + ''' As Date) AND CAST(''' + #endDate + ''' As Date) '
I would think would work, or at least be close. Your issue is #startDate and #endDate are not actually declared within the separate scope that is executing your dynamic sql.
Basically exec(#sql) is a separate scope from the stored proc scope that is actually declaring your #startDate and #endDate.

Is it possible to set the select list dynamically in MSSQL server2008?

I have a requirement to populate the select list dynamically, Could you please suggest any solution?
Example:
DECLARE #DATE CHAR
SET #DATE='E.TERMINATION_DATE'
--SET #DATE='E.HIRE_DATE'
SELECT E.ID,E.FIRSTNAME,E.LASTNAME, #DATE FROM DBO.EMPLOYEES E
Is it possible to set the column name in select query?
For some query i need to set the variable #DATE as TERMINATION DATE and for some query i need to set #DATE as E.HIREDATE.
When i will run the query based on the TERMINATION_DATE then i will comment in the other option.
or do you have any other workaround?
You can use the Dynamic sql. But you should read this blog to know about it.
DECLARE #DATE VARCHAR(100),
#SQL VARCHAR(MAX)
IF YOURCONDITION
BEGIN
SET #DATE='E.TERMINATION_DATE'
END
ELSE
BEGIN
SET #DATE='E.HIRE_DATE'
END
SET #SQL = 'SELECT E.ID,E.FIRSTNAME,E.LASTNAME,' + #DATE +' FROM DBO.EMPLOYEES E'
exec sp_executesql #SQL
you can use variables in select query but you should assign that query to some variable and execute that variable
because in SSMS at first it will checks(run time) then it executes. In our scenario the variable is assigning at execution only
so we need to assign it to variable as #coderofcode told
DECLARE #DATE VARCHAR(100),
#SQL VARCHAR(MAX)
SET #DATE='E.TERMINATION_DATE'
SET #SQL = 'SELECT E.ID,E.FIRSTNAME,E.LASTNAME,' + #DATE +' FROM DBO.EMPLOYEES E'
exec(#sql)
I was writing a function for which i need to use execution_date for some case and for some other case i need to use hire_date.
So i think i can now populate this things dynamically and it's a great invention for me. Thanks all specially Giorgi, coder of code and koushik.
I am using this pseudo code here.
--Setting the condition parameters
DECLARE #HIRE_DATE DATETIME,
SET #HIRE_DATE= SELECT MIN(HIRE_DATE) FROM E.EMPLOYEES WHERE E.PERSON_ID>30000
--based on condition setting the variable dynamically.
IF #HIRE_DATE IS NULL
BEGIN
SET #DATE='E.TERMINATION_DATE'
END
ELSE
BEGIN
SET #DATE='E.HIRE_DATE'
END
--setting the sql to execute.
SET #SQL = 'SELECT COUNT(E.NR) AS ACTIVITIES,E.CLI_FIRSTNAME,E.CLI_LASTNAME,E.DEBTORNR,' + #DATE +' FROM DBO.EMPLOYEES E
GROUP BY E.CLI_FIRSTNAME,E.CLI_LASTNAME,E.DEBTORNR,' + #DATE
exec(#sql)

I am getting an error to define again the scalar variable even when i have defined it in SQL Server stored procedure

I have written the code as follows:
CREATE PROCEDURE [dbo].[TEST22]
#database_name VARCHAR(200),
/*Enter the Start Date and End date in the format MM/DD/YYYY*/
#Start_Date VARCHAR(200),
#End_Date VARCHAR(200)
AS
BEGIN
DECLARE #querystring VARCHAR(MAX)
--JOINS THE VENDOR MASTER FILE WITH THE PAYMENTS FILE TO IDENTIFY VENDORS WHO DO
-- NOT APPEAR IN THE PAYMENTS FILE FOR THE GIVEN PERIOD OF ANALYSIS
SET NOCOUNT ON;
IF EXISTS(SELECT * FROM SYSOBJECTS WHERE ID = OBJECT_ID('dummy1'))
DROP TABLE dummy1
DECLARE #Test Nvarchar(50)
SET #test =N'"Test1"'
SET #querystring = 'select #test as Test1, getdate() as time1
into dbo.dummy1
from sys.tables'
EXEC (#querystring)
END
and when I run this code I am getting the following error:
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#test".
Please suggest what the error is?
SET #querystring ='select #test as Test1, getdate() as time1
When this query is executing, it is executing as a standalone query, in which #test is not defined
EXEC (#querystring)
during this execution, the parameter #test must be defined.
In my opinion what you wish to achieve is
SET #querystring = 'select ' + #test + ' as Test1, getdate() as time1 ..... '
This concatenation will put the value of #test in the query and the new query will be
SELECT N'"Test1"' as Test1, getdate() as time1....
Glad to help! Please remember to accept the answer if you found it helpful.
As #Manish points out, #test isn't defined within the scope of your EXEC statement. However, a cleaner way to work with it than their proposal is to use sp_executesql:
SET #querystring = 'select #test as Test1, getdate() as time1
into dbo.dummy1
from sys.tables'
DECLARE #Parms nvarchar(max)
SET #Parms = N'#test nvarchar(50)'
EXEC sp_executesql #querystring,#Parms,#test
This keeps it as a separate parameter within the inner scope of the EXEC and so avoids any potential concerns about SQL Injection that arise whenever you concatenate SQL code and data.

Initializing table name to be used in a stored procedure in SQL Server

I am trying to create a stored procedure to achieve the following in the stored procedure
DECLARE #TBLNAME VARCHAR(128)
SET #TBLNAME = SELECT PAR_VALUE FROM DBO.PARAMETERS WHERE PAR_NAME='SALES_ORDERS_TABLE';
The PAR_VALUE column in the PARAMETERS table contains the name of the table of the Sales Order table.
I now want to use this table name in the stored procedure, and count the number of rows in this table.
DECLARE #SQL NVARCHAR(4000)
# SQL = SELECT COUNT(*) FROM '[#TBLNAME]'
However, when I try to run this, there are multiple errors.
Can you please help me by guiding on how to do this?
I just now tried this code:
CREATE PROCEDURE JCOUNT_SO
AS
DECLARE #TBLNAME NVARCHAR(512)
SELECT #TBLNAME=(SELECT PAR_VALUE FROM DBO.PARAMETERS WHERE PAR_NAME='SALES_ORDERS_TABLE')
DECLARE #SQL NVARCHAR(4000)
SELECT #SQL='SELECT COUNT(*) AS #_OF_RECORDS INTO SO_COUNT
FROM' '+QUOTENAME(#TBLNAME)''
EXEC SP_EXECUTESQL #SQL;
Error Message: Invalid Object Name: 'TEST.DBO.SO_MASTER'
Please help on this code.
Please read defination of sp_executesql for reference. Procedure below returns value as an output parameter from dynamic query rather than inserting into a table. You can manipulate query as per your requirement.
CREATE PROCEDURE JCOUNT_SO
AS
DECLARE #TBLNAME nvarchar(512)
--Obtain table name. Top 1 is used to pick first record rather than last record in case query returns more than one record.
SELECT TOP 1 #TBLNAME = PAR_VALUE FROM DBO.PARAMETERS WHERE PAR_NAME='SALES_ORDERS_TABLE'
DECLARE #SQL NVARCHAR(4000)
DECLARE #Count int
SET #SQL ='SELECT #Count = COUNT(*) FROM ' + #TBLNAME
--Define parameters to be passed i.e. #Count is being passed as output parameter
EXEC SP_EXECUTESQL #SQL, N'#Count int OUTPUT', #Count output
select #Count
end
Notes from MSDN
Query i.e. #SQL can contain parameters having the same form as a variable name and each parameter included in #SQLmust have a corresponding entry in both the #params parameter definition list and the parameter values list
1 point I can say is ... it should be SET #SQL = SELECT ...
and one more thing is you can try converting the result to NVARCHAR.
use SELECT Convert(NVARCHAR(4000),Count(*)) FROM ...