SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX),
#servername NVARCHAR(255)
SET #servername = '[s-printstream]'
--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' + ' #servername ' + '.[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 sp_executesql #sql
,N'#JobNumber Varchar(25)'
,#JobNumber = 417133
Could anyone please help me find out how I would pass my server name dynamically as well as the database name? When I try to do it, I get this error:
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#servername"
Any help is appreciated.
Thanks
or pass #servername value into sql command
EXEC sp_executesql #sql
,N'#JobNumber Varchar(25),#servername nvarchar(255)'
,#JobNumber = 417133,#servername=#servername
Related
I am trying to create the below dynamic update query with some variables and for some reason, it's not working inside the stored procedure. Can someone suggest to me where I am doing wrong and what's the best practice by avoiding the SQL Injection as well?
DECLARE #SQL NVARCHAR(MAX)
DECLARE #COLUMN1 NVARCHAR(10)
DECLARE #COLUMN2 NVARCHAR(10)
DECLARE #TABLENAME NVARCHAR(10)
SET #SQL = 'UPDATE TL
SET '+ #COLUMN1 + '= AB.COLUMN1,'
+ #COLUMN2 + '= AB.COLUMN2
FROM' + #TABLENAME + ' TL
JOIN ABACUS AB
ON TL.REF = AB.REF
AND TL.SUBS = AB.SUBS
WHERE ' + #COLUMN1 + ' IS NULL
AND ' + #COLUMN2 +' IS NULL';
SET #COLUMN1 = (SELECT CONCAT('USER_ID', '8'))
SET #COLUMN2 = (SELECT CONCAT('USER_ID', '6'))
SET #TABLENAME = 'POLICYREF';
EXEC sys.sp_executesql #SQL, #TABLENAME, #COLUMN1, #COLUMN2;
SET #TABLENAME = 'USERREF';
EXEC sys.sp_executesql #SQL, #TABLENAME, #COLUMN1, #COLUMN2;
You need dynamic SQL, not parameters. You can't parameterize column names or table names. So something like:
DECLARE #SQL NVARCHAR(MAX)
DECLARE #COLUMN1 NVARCHAR(10) = 'USER_ID8'
DECLARE #COLUMN2 NVARCHAR(10) = 'USER_ID6'
DECLARE #TABLENAME NVARCHAR(10) = 'POLICYREF'
SET #SQL = 'UPDATE TL
SET '+ quotename(#COLUMN1) + '= AB.COLUMN1,'
+ quotename(#COLUMN2) + '= AB.COLUMN2
FROM ' + quotename(#TABLENAME) + ' TL
JOIN ABACUS AB
ON TL.REF = AB.REF
AND TL.SUBS = AB.SUBS
WHERE ' + quotename(#COLUMN1) + ' IS NULL
AND ' + quotename(#COLUMN2) +' IS NULL';
EXEC (#SQL)
SET #TABLENAME NVARCHAR(10) = 'USERREF'
SET #SQL = 'UPDATE TL
SET '+ quotename(#COLUMN1) + '= AB.COLUMN1,'
+ quotename(#COLUMN2) + '= AB.COLUMN2
FROM ' + quotename(#TABLENAME) + ' TL
JOIN ABACUS AB
ON TL.REF = AB.REF
AND TL.SUBS = AB.SUBS
WHERE ' + quotename(#COLUMN1) + ' IS NULL
AND ' + quotename(#COLUMN2) +' IS NULL';
EXEC (#SQL)
Not a huge fan of this but, given that, create a stored procedure OR re-arrange to execute each after updating the #SQL, here is the stored procedure example:
Note this is missing production level things like a transaction, TRY CATCH etc. and is only for an basic UNTESTED example
CREATE PROCEDURE dbo.MyFunQuery
#SQL NVARCHAR(MAX),
#COLUMN1 NVARCHAR(10),
#COLUMN2 NVARCHAR(10),
#TABLENAME NVARCHAR(10)
AS
BEGIN
SET #SQL = 'UPDATE TL
SET '+ #COLUMN1 + '= AB.COLUMN1,'
+ #COLUMN2 + '= AB.COLUMN2
FROM ' + #TABLENAME + ' AS TL
JOIN ABACUS AS AB
ON TL.REF = AB.REF
AND TL.SUBS = AB.SUBS
WHERE ' + #COLUMN1 + ' IS NULL
AND ' + #COLUMN2 + ' IS NULL;';
EXECUTE ( #SQL );
END
--Now to call it:
DECLARE #COLUMN1 NVARCHAR(10) = 'USER_ID8',
#COLUMN2 NVARCHAR(10) = 'USER_ID6';
EXECUTE dbo.MyFunQuery #COLUMN1, #COLUMN2, #TABLENAME='POLICYREF';
EXECUTE dbo.MyFunQuery #COLUMN1, #COLUMN2, #TABLENAME='USERREF';
my stored procudure is :
ALTER PROCEDURE [dbo].[Asbabbazi_A]
#name_product nvarchar(50),
#first_price int,
#final_price int,
#collection_1 nvarchar(30),
#id_state tinyint
AS
BEGIN
DECLARE #SQLstring nvarchar(1000)
DECLARE #PARAMS nvarchar(1000)
set #SQLstring = 'SELECT IDproduct,name_product,first_price,final_price,max_registered_price,
date_record_shamsi,final_date_view_shamsi,
count_views,image_1,collection_1 from Table_asbabbazi where active=0 '
if(#name_product != 'no name')
set #SQLstring = #SQLstring + ' AND (name_product LIKE %#name_product%)'
if (#final_price != 0)
set #SQLstring = #SQLstring + ' AND ( first_price between #first_price AND #final_price )'
if (#collection_1 != 'انتخاب کنید')
set #SQLstring = #SQLstring + ' AND (collection_1 = #collection_1 )'
if (#id_state != 0)
set #SQLstring = #SQLstring + ' AND (id_state = #id_state )'
execute #SQLstring
END
when execute show this error:
The name 'SELECT IDproduct,name_product,first_price,final_price,max_registered_price,
date_record_shamsi,final_date_view_shamsi,
count_views,image_1,collection_1 from Table_asbabbazi where active=0 AND (name_product LIKE %#name_product%) AND (collection_1 = #collection_1 )' is not a valid identifier.
please help
Some parameters in a query string are not parsed correctly, and you are using dynamic sql it must be executed by EXECUTE sp_executesql statement. This is the correct way to execute dynamic sql:
ALTER PROCEDURE [dbo].[Asbabbazi_A]
#name_product nvarchar(50),
#first_price int,
#final_price int,
#collection_1 nvarchar(30),
#id_state tinyint
AS
BEGIN
DECLARE #SQLstring nvarchar(1000)
DECLARE #PARAMS nvarchar(1000)
set #SQLstring = 'SELECT IDproduct,name_product,first_price,final_price,max_registered_price,
date_record_shamsi,final_date_view_shamsi,
count_views,image_1,collection_1 from Table_asbabbazi where active=0 '
if(#name_product != 'no name')
set #SQLstring = #SQLstring + ' AND name_product LIKE ''%' + #name_product + '%''' + ' '
if (#final_price != 0)
set #SQLstring = #SQLstring + ' AND first_price between ' + CONVERT(nvarchar(1000), #first_price) + ' AND ' + CONVERT(nvarchar(1000), #final_price) + ' '
if (#collection_1 != 'انتخاب کنید')
set #SQLstring = #SQLstring + ' AND collection_1 = ''' + #collection_1 + ''' '
if (#id_state != 0)
set #SQLstring = #SQLstring + ' AND id_state = ' + CONVERT(nvarchar(1000), #id_state) + ' '
EXECUTE sp_executesql #SQLstring
END
In brief,
put declared SQLstring inside Parenthesis when execute stored procedure like this
👉 EXECUTE usp_executeSql (#SQLstring)
Example:
False ❌
EXECUTE usp_executeSql #SQLstring
True ✔
EXECUTE usp_executeSql (#SQLstring)
You have your variables inside quotes thus making them string literals. Instead of this sort of thing:
set #SQLstring = #SQLstring + ' AND (collection_1 = #collection_1 )'
you need this sort of thing:
set #SQLstring = #SQLstring + ' AND (collection_1 = '
+ #collection_1 + ' )'
I have a function which returns the comma separate values, but when I use
COALESCE(#Jiraids + ', ', '')
I get an error.
ALTER FUNCTION [dbo].[getCommonJiraIds](
#selct varchar(100),
#whereClause varchar(100),
#id varchar(100),
#TEST_RESULT_INFO_ID varchar(20) )
RETURNS varchar(max)
AS
BEGIN
DECLARE #Jiraids VARCHAR(8000)
DECLARE #sql varchar(max)
SET #whereClause = 'dbo.SNSTestResults.JIRA_ID <> '' AND dbo.SNSTestResults.'+#whereClause+ ''+ QUOTENAME(#id,'''') + 'AND dbo.SNSTestResults.Test_result_info_ID_FK LIKE '+QUOTENAME(#TEST_RESULT_INFO_ID,'''')
SET #sql = 'Select #Jiraids = COALESCE(#Jiraids + '', '', '') + case when (#selct LIKE Jira_ID_Maped) then Jira_ID_Maped else Jira_ID end
FROM dbo.TestCaseList INNER JOIN dbo.SNSTestResults ON dbo.TestCaseList.TestCaseListID = dbo.SNSTestResults.TestCaseListID_FK'
set #sql = #sql + #WhereClause
EXEC #sql
RETURN ( select #Jiraids);
END
When I execute the above function I got this error:
Msg 203, Level 16, State 2, Procedure GetDailyCrJiraTable, Line 159
The name 'Select #Jiraids =COALESCE(#Jiraids + ', ', ') + case when (#selct LIKE Jira_ID_Maped) then Jira_ID_Maped else Jira_ID end FROM dbo.TestCaseList INNER JOIN dbo.SNSTestResults ON dbo.TestCaseList.TestCaseListID = dbo.SNSTestResults.TestCaseListID_FKdbo.SNSTestResults.JIRA_ID <> ' AND dbo.SNSTestResults.Jira_ID_Maped'UIBUG-4533'AND dbo.SNSTestResu' is not a valid identifier.
Somebody please help me to fix this issue.
SET #whereClause = 'dbo.SNSTestResults.JIRA_ID <> '''' AND dbo.SNSTestResults.'+#whereClause+ ''+ QUOTENAME(#id,'''') + 'AND dbo.SNSTestResults.Test_result_info_ID_FK LIKE '+QUOTENAME(#TEST_RESULT_INFO_ID,'''')
you need more ' after dbo.SNSTestResults.JIRA_ID <>
You have to add more ' to your COALESCE function as below
Select #Jiraids = COALESCE(#Jiraids + '', '', '''')
and as I said in comment you have to change this dbo.SNSTestResults.JIRA_ID <> ''
to dbo.SNSTestResults.JIRA_ID <> '''' AND
ALTER FUNCTION [dbo].[getCommonJiraIds](
#selct varchar(100),
#whereClause varchar(100),
#id varchar(100),
#TEST_RESULT_INFO_ID varchar(20) )
-- your four inputs
RETURNS varchar(max)
AS
BEGIN
DECLARE #Jiraids VARCHAR(8000)
DECLARE #sql varchar(max)
SET #whereClause = 'dbo.SNSTestResults.JIRA_ID <> ''
AND dbo.SNSTestResults.'+#whereClause+ ''+ QUOTENAME(#id,'''')
+ 'AND dbo.SNSTestResults.Test_result_info_ID_FK LIKE '+QUOTENAME(#TEST_RESULT_INFO_ID,'''')
you do not know it yet, but your Query does not actually have a WHERE clause written in.
I hope you are not actually expecting the programmer to write extra
code in your function everytime it is used.
SET #sql = 'Select #Jiraids = COALESCE(#Jiraids + '', '', '') + case when (#selct LIKE Jira_ID_Maped) then Jira_ID_Maped else Jira_ID end
FROM dbo.TestCaseList INNER JOIN dbo.SNSTestResults ON dbo.TestCaseList.TestCaseListID = dbo.SNSTestResults.TestCaseListID_FK
Your #selct has not been correctly identified. SQL SERVER cannot know
at compile time that it is a #variable.
Also, are you sure your function will only return one row? In some cases, being explicit about the expected occurrence (should someone actually use a '%' in their PREDICATE) can prevent a future breakdown in the code.
set #sql = #sql + #WhereClause
EXEC #sql
Thankfully, SO exists to help people out. :D
A correct version could be like the following:
ALTER FUNCTION [dbo].[getCommonJiraIds](
#selct varchar(100),
#whereClause varchar(100),
#id varchar(100),
#TEST_RESULT_INFO_ID varchar(20) )
-- your four inputs
RETURNS varchar(max)
AS
BEGIN
DECLARE #Jiraids VARCHAR(8000)
DECLARE #sql varchar(max)
SET #sql = '
Select #Jiraids = TOP 1 COALESCE(#Jiraids + '', '', '') + CASE WHEN (' + #selct + ' = Jira_ID_Maped)
THEN Jira_ID_Maped
ELSE Jira_ID END
FROM dbo.TestCaseList
INNER JOIN dbo.SNSTestResults ON dbo.TestCaseList.TestCaseListID = dbo.SNSTestResults.TestCaseListID_FK'
SET #whereClause = 'WHERE dbo.SNSTestResults.JIRA_ID <> ''
AND dbo.SNSTestResults.'+#whereClause+ ''+ QUOTENAME(#id,'''')
+ 'AND dbo.SNSTestResults.Test_result_info_ID_FK LIKE '+QUOTENAME(#TEST_RESULT_INFO_ID, '')
set #sql = #sql + #WhereClause
EXEC #sql
RETURN ( select #Jiraids);
END
I'm got trouble with paging on SQL server 2005 which run query 2 times (get data and total rows). My demo proc below which base on Northwind database. Please help me to how to get total rows without query again.
CREATE PROCEDURE [dbo].[SearchEmployees]
#search nvarchar(4000)
,#orderBy varchar(200)
,#PageSize int
,#PageIndex int
,#TotalRowsNumber int output
AS
DECLARE #PageLowerBound int
DECLARE #PageUpperBound int
SET #PageLowerBound = #PageSize * #PageIndex
SET #PageUpperBound = #PageSize + #PageLowerBound
--Default order by to first column
IF (#OrderBy is null or LEN(#OrderBy) < 1)
BEGIN
SET #OrderBy = 'EmployeeID DESC'
END
-- SQL Server 2005 Paging
declare #SQL as nvarchar(4000)
declare #SQLCOUNT as nvarchar(4000)
declare #Param as nvarchar(500)
SET #SQL = 'WITH PageIndex AS ('
SET #SQL = #SQL + ' SELECT '
IF #PageSize > 0
BEGIN
SET #SQL = #SQL + ' TOP ' + convert(nvarchar, #PageUpperBound)
END
SET #SQL = #SQL + ' ROW_NUMBER() OVER (ORDER BY ' + #OrderBy + ') as RowIndex '
SET #SQL = #SQL + ' ,EmployeeID'
SET #SQL = #SQL + ', LastName'
SET #SQL = #SQL + ', FirstName'
SET #SQL = #SQL + ', Title'
SET #SQL = #SQL + ' FROM employees'
IF Len(#Search) > 0
BEGIN
SET #SQL = #SQL + ' ' + #Search
END
SET #SQL = #SQL + ') SELECT '
SET #SQL = #SQL + ' EmployeeID'
SET #SQL = #SQL + ', LastName'
SET #SQL = #SQL + ', FirstName'
SET #SQL = #SQL + ', Title'
SET #SQL = #SQL + ' FROM PageIndex '
SET #SQL = #SQL + ' WHERE RowIndex > ' + convert(nvarchar, #PageLowerBound)
IF #PageSize > 0
BEGIN
SET #SQL = #SQL + ' AND RowIndex <= ' + convert(nvarchar, #PageUpperBound)
END
--Get Row Count
SET #SQLCOUNT = 'SELECT #TotalRowsNumber = count(EmployeeID)
FROM employees'
SET #Param = N'#Search nvarchar(2000),#TotalRowsNumber INT OUTPUT'
IF LEN(#Search) > 0
BEGIN
SET #SQLCOUNT = #SQLCOUNT + #Search
END
exec sp_executesql #SQL
exec sp_executesql #SQLCOUNT, #Param,#Search=#Search,#TotalRowsNumber = #TotalRowsNumber OUT
Thanks in advance!
Try Like this, See it as an example
CREATE Procedure usp_GetBookings
#pageIndex int,
#pageSize tinyint
as
;with CTE as
(
Select Distinct ROW_NUMBER() over( order by ssi.SSItineraryID desc) as seq ,Count(*) over() as TotalRow,ssi.SSItineraryID
from SightSeeingItinerary as ssi
)
select * from CTE
where cte.seq between (#pageIndex-1) * #pageSize+1 and ((#pageIndex-1) * #pageSize +(#pageSize))
I've written the below code to set filepath column in my table as 'F:\DataMigration\Wise\DELTA_20121008\Attachments\SR\SR_1.txt'
where SR_1 is file_name column
.txt is file_ext column from my table.
but after executing following procedure, I'm getting filepath column in table as
'F:\DataMigration\Wise\DELTA_20121008\Attachments\file_name.file_ext'
means It's treating column names as string, how i can make it as column so it will
use values in that column.
alter procedure [dbo].[WISEMissingAttachmentReportGenerator]
(
#tablename varchar(255), #pathonlocal nvarchar(255)
)
as
begin
--step 1
exec dbo.proc_alter_table #tablename
--step 2
EXEC ('update '+ #tablename +
' set filepath = '''+ #pathonlocal + ' file_name'+'.'+'file_ext''')
EXEC('Select * from '+#tablename)
end
exec [dbo].[WISEMissingAttachmentReportGenerator] [WISE.Non_VP_Service_Request_Attachments_File_Check_Analysis],
N'F:\DataMigration\Wise\DELTA_20121008\Attachments\SR\'
Try;
EXEC('UPDATE '+ #tablename +
' SET filepath = '''+ #pathonlocal + ''' + file_name + '''+'.'+''' + file_ext')
Equal as;
UPDATE [YourTable] SET filepath = 'YourPath' + file_name + '.' + file_ext
Try changing your statement to this:
EXEC ('update '+ #tablename +
' set filepath = '''+ #pathonlocal + ''' + file_name + ''.'' + file_ext')
declare #tblnm varchar(20) = 'test'
declare #upda varchar(20) = 'update '
declare #set varchar(25) = ' set'
declare #id varchar(25) = ' id'
declare #cmd varchar(1000)
set #cmd = #upda + #tblnm + #set + #id + '=7'
exec(#cmd)
SAMPLE SQL UPDATE QUERY - FOR BUILDING TABLENAME DYNAMICALLY
EXECUTED GUYS - THIS IS CALL JUGAAAAAAAAAD [NO NEED TO GET INTO ''' STUFF]