The code below works well. I however have issues trying to turn it into a like statement that I need some assistance with
CREATE PROCEDURE [dbo].[searcher]
#deliverer nvarchar (100)
AS
BEGIN
DECLARE #sql nvarchar(1000)
SET #sql = 'SELECT location, deliverer, charger FROM Store where 1=1'
IF (#deliverer IS NOT NULL)
SET #sql = #sql + ' and deliverer =#pt'
DECLARE #t1 as TABLE
(
location varchar(1000),
deliverer varchar(100),
charger varchar(100)
)
INSERT INTO t1
EXEC sp_executesql #sql,
N'#pt nvarchar(100)',
#pt=location
SELECT * FROM t1
END
So far, I have tried the code below but with not much success
DECLARE #pt nvarchar (100)
SET #pt = '%' + #pt + '%'
IF (#deliverer IS NOT NULL)
SET #sql = #sql + ' and deliverer like #pt'
I have also tried;
DECLARE #pt nvarchar (100)
IF (#deliverer IS NOT NULL)
SET #sql = #sql + ' and deliverer like ''% + #pt + %'''
If your stored procedure parameter is #deliverer and your dynamic SQL parameter is #pt, I believe your sp_executesql execution should assign the parameter as #pt = #deliverer.
As for adding wildcards, you can either add them before the call with
SET #deliverer = '%' + #deliverer + '%'
or add them in the dynamic SQL with
SET #sql = #sql + ' and deliverer like ''%'' + #pt + ''%'''
Note the doubled up quotes around the %. The variable #pt is not quoted
I need to update a specific set of columns with null value, but when I'm trying to pass null value to dynamic SQL I'm not getting any error or output.
DECLARE #Value VARCHAR(100)
SELECT #Value = null
DECLARE #TableName VARCHAR(1000),#ColumnName VARCHAR(100)
DECLARE #Sql NVARCHAR(MAX)
SET #Sql= N''
DECLARE UpdatePlantId_Crsr CURSOR
STATIC FOR
SELECT ST.name AS TableName,SC.name AS ColumnName
FROM
sys.columns SC
INNER JOIN
sys.tables ST ON ST.object_Id = SC.Object_Id
WHERE
SC.name like '%_MLP'
--AND ST.name not like 'tPlant'
OPEN UpdatePlantId_Crsr
IF ##CURSOR_ROWS > 0
BEGIN
FETCH NEXT FROM UpdatePlantId_Crsr INTO #TableName,#ColumnName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #Sql= N''
SELECT #Sql = #Sql + N' UPDATE '+#TableName +' SET '+#ColumnName+ '= '+ #Value +'
'
PRINT #Sql
--EXEC(#Sql)
FETCH NEXT FROM UpdatePlantId_Crsr INTO #TableName,#ColumnName
END
END
CLOSE UpdatePlantId_Crsr
DEALLOCATE UpdatePlantId_Crsr
I suspect that something is wrong with your application if you need to use dynamic SQL to set tables and columns to NULL. That said, the question can still be answered.
You should use sp_executesql. But given that the table and column names cannot be passed in, just set up the SQL correctly:
SET #Sql = N'UPDATE ' + #TableName + ' SET ' + #ColumnName + ' = NULL' ;
EXEC sp_executesql #sql; -- yuo can still use it with no parameters
I am not sure why you are concatenating the #sql string, so I removed that.
Note that + NULL returns NULL -- both for string concatenation and addition.
IF EXISTS ( 'SELECT ' +#TextField+','+#ValueField+' FROM ' + #TableName + ' WHERE ' + #TextFieldPara + '=' +#ValueFieldPara + ' ORDER BY ' +#TextField+' ASC;')
BEGIN
SET #Message = #TextField + ' Already Exist...'
END
ELSE
BEGIN
SET #Message = 'TRUE'
END
by using this query i am trying to check in all table whether inserted value for field Repeated or Not.
when i write this query in store procedure i got an error at
IF EXISTS ( 'SELECT ' +#TextField+','+#ValueField+' FROM ' + #TableName + ' WHERE ' + #TextFieldPara + '=' +#ValueFieldPara + ' ORDER BY ' +#TextField+' ASC;') "
all variables are populated from c# back end.
is there any solution?
If you want to set the table, you need dynamic SQL. Here is one method:
declare #sql nvarchar(max);
declare #cnt int;
set #sql = '
SELECT #cnt = COUNT(*)
FROM #TableName
WHERE #TextFieldPara = #ValueFieldPara
');
set #sql = replace(#sql, '#TableName', #TableName);
set #sql = replace(#sql, '#TextFieldPara', #TextFieldPara);
set #sql = replace(#sql, '#ValueFieldPara', #ValueFieldPara);
exec sp_executesql(#sql, N'#cnt int output', #cnt=#cnt output);
if (#cnt > 0) . . .
begin
set #Message = #TextField + ' Already Exist...';
end
else
begin
set #Message = 'TRUE';
end;
I simplified the query because you don't need a select list or order by for determining the existing of values. I also used count(*) just because it is simpler to express. If you care about performance, there are better methods, such as a case with an exists in it.
Similarly, you should use quotename() for the identifiers in the query. You don't have that in your sample code, but it is a best practice.
DECLARE #sql VARCHAR(8000)
,#jobNumber VARCHAR(25)
,#DBName VARCHAR(30)
SET #jobNumber = '417133'
DROP TABLE #Actual
CREATE TABLE #Actual (
jobnumber INT
,firstNameCounts VARCHAR(25)
,lastNameCounts VARCHAR(25)
,address1Counts VARCHAR(25)
,address2Counts VARCHAR(25)
,cityCounts VARCHAR(25)
,stateCounts VARCHAR(25)
,zipCounts VARCHAR(25)
,inHomeDateCounts VARCHAR(25)
)
SET #sql = 'INSERT INTO #actual (jobnumber,firstNameCounts,lastNameCounts ,
address1Counts, address2Counts, cityCounts, stateCounts, zipCounts,
inHomeDateCounts) '
SET #sql = #sql + ' Select s.jobnumber, count(s.firstName) AS
[firstNameCounts], Count (s.lastName) AS [lastNameCounts], Count (s.Address1)
As [address1Counts], Count (s.address2)-Count (address2) AS '
SET #sql = #sql + ' [address2Counts], Count (s.City) AS [cityCounts], Count
(s.State) AS [stateCounts], Count (s.Zip) AS [zipCounts], Count
(jb.inHomeDate) AS [inHomeDateCounts] '
SET #sql = #sql + ' From [s-portaldb1].[tdis_417133) + ].[dbo].
[tblStandardFinal] s '
SET #sql = #sql + ' INNER JOIN [s-printstream].[tdSchedule2].[dbo].
[tblJobTicketActions] jb '
SET #sql = #sql + ' ON jb.psFlagJobNumber = s.jobNumber '
*SET #sql = #sql + ' where jobNumber = #jobNumber '* Getting error here
SET #sql = #sql + ' group by jobNumber '
PRINT #SQL
EXEC (#sql)
SELECT *
FROM #Actual
I am getting this
Error: Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#jobNumber". I have declared the value and not sure what the reason could be.
any help would be appreciated.
Because you are executing SQL with exec() and have not provided a declaration for that variable inside the executed sql. #sql will be executed in its own context, and will not be able to access the variable of the same name that you have declared outside of the executed sql.
You could instead use sp_executesql which allows for parameter declaration and passing of parameters.
declare #sql nvarchar(max); /* nvarchar() instead of varchar() */
...
exec sp_executesql #sql, N'#JobNumber Varchar(25)', #JobNumber;
dynamic sql reference:
The curse and blessings of dynamic SQL - Erland Sommarskog
sp_executesql
You are running dynamic SQL - it runs in its own context and doesn't have access to the declared variables you have.
Either construct the dynamic SQL with the value being passed in (in the SQL string you later execute), or figure out how to do this without dynamic SQL (I don't see a reason for building the string and the EXECuting it).
All that string concatenation seems completely superfluous.
So instead of this:
SET #sql = 'INSERT INTO #actual (jobnumber,firstNameCounts,lastNameCounts ,
address1Counts, address2Counts, cityCounts, stateCounts, zipCounts,
inHomeDateCounts) '
SET #sql = #sql + ' Select s.jobnumber, count(s.firstName) AS
[firstNameCounts], Count (s.lastName) AS [lastNameCounts], Count (s.Address1)
As [address1Counts], Count (s.address2)-Count (address2) AS '
SET #sql = #sql + ' [address2Counts], Count (s.City) AS [cityCounts], Count
(s.State) AS [stateCounts], Count (s.Zip) AS [zipCounts], Count
(jb.inHomeDate) AS [inHomeDateCounts] '
SET #sql = #sql + ' From [s-portaldb1].[tdis_417133) + ].[dbo].
[tblStandardFinal] s '
SET #sql = #sql + ' INNER JOIN [s-printstream].[tdSchedule2].[dbo].
[tblJobTicketActions] jb '
SET #sql = #sql + ' ON jb.psFlagJobNumber = s.jobNumber '
SET #sql = #sql + ' where jobNumber = #jobNumber '
SET #sql = #sql + ' group by jobNumber '
PRINT #SQL
EXEC (#sql)
You should just have:
INSERT INTO #actual (jobnumber,firstNameCounts,lastNameCounts ,
address1Counts, address2Counts, cityCounts, stateCounts, zipCounts,
inHomeDateCounts)
Select s.jobnumber, count(s.firstName) AS
[firstNameCounts], Count (s.lastName) AS [lastNameCounts], Count (s.Address1)
As [address1Counts], Count (s.address2)-Count (address2) AS
[address2Counts], Count (s.City) AS [cityCounts], Count
(s.State) AS [stateCounts], Count (s.Zip) AS [zipCounts], Count
(jb.inHomeDate) AS [inHomeDateCounts]
From [s-portaldb1].[tdis_417133) + ].[dbo].
[tblStandardFinal] s
INNER JOIN [s-printstream].[tdSchedule2].[dbo].[tblJobTicketActions] jb
ON jb.psFlagJobNumber = s.jobNumber
where jobNumber = #jobNumber
group by jobNumber
I have a stored procedure which I have to rewrite using sp_executesql. I want to use sp_executesql instead of exec because of performance issue on my SQL Server instance.
Here is my code:
ALTER PROCEDURE [dbo].[sp_TestSp1]
#Type1 VARCHAR(256)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sqlCommand varchar(2000) = ''
DECLARE #columnList varchar(1000) = ''
DECLARE #dynamicSql varchar(1000) = ''
IF (#Type1 IS NOT NULL )
BEGIN
SET #dynamicSql = #dynamicSql + 'AND tbl1.DTypeID IN ( '+ #Type1+ ' )'
END
SET #columnList = 'SELECT DISTINCT tbl2.ID, Name AS PName '
SET #sqlCommand = #columnList
+ ' FROM tbl1 '
+ ' INNER JOIN tbl3 ON tbl1.NID= tbl3.NID '
+ ' INNER JOIN tbl4 ON tbl3.DID = tbl4.DID '
+ ' WHERE TT=1 AND IsActive=1 AND tbl1.DTypeID IN (1,3,5)'
+ #dynamicSql
EXEC (#sqlCommand)
Replace your EXEC (#sqlCommand) statement with the following.
EXECUTE sp_executesql #sqlCommand
TechNet Link