SQL Stored Procedure select statement - sql-server

I have another field in my database table called FileName, I want the record to be selected by FileName. What should I add to the code.
ALTER PROCEDURE [dbo].[spx_Pager]
#PageNo int = 1,
#ItemsPerPage int = 2,
#TotalRows int out,
#f_name nvarchar(50)
AS
BEGIN
SET NOCOUNT ON
DECLARE
#StartIdx int,
#SQL nvarchar(max),
#SQL_Conditions nvarchar(max),
#EndIdx int
IF #PageNo < 1 SET #PageNo = 1
IF #ItemsPerPage < 1 SET #ItemsPerPage = 10
SET #StartIdx = (#PageNo -1) * #ItemsPerPage + 1
SET #EndIdx = (#StartIdx + #ItemsPerPage) - 1
SET #f_name = (#f_name)
SET #SQL = 'SELECT FilePath
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS Row, *
FROM tblFiles ) AS tbl WHERE Row >= '
+ CONVERT(varchar(9), #StartIdx) + ' AND
Row <= ' + CONVERT(varchar(9), #EndIdx)
EXEC sp_executesql #SQL
SET #SQL = 'SELECT #TotalRows=COUNT(*) FROM tblFiles'
EXEC sp_executesql
#query = #SQL,
#params = N'#TotalRows INT OUTPUT',
#TotalRows = #TotalRows OUTPUT
END

You didn't give me much to go on. But is this what you need?
ALTER PROCEDURE [dbo].[spx_Pager]
#PageNo int = 1,
#ItemsPerPage int = 2,
#TotalRows int out,
#f_name nvarchar(50)
AS
BEGIN
SET NOCOUNT ON
DECLARE
#StartIdx int,
#SQL nvarchar(max),
#SQL_Conditions nvarchar(max),
#EndIdx int
IF #PageNo < 1 SET #PageNo = 1
IF #ItemsPerPage < 1 SET #ItemsPerPage = 10
SET #StartIdx = (#PageNo -1) * #ItemsPerPage + 1
SET #EndIdx = (#StartIdx + #ItemsPerPage) - 1
SET #f_name = (#f_name)
SET #SQL = 'SELECT FilePath
FROM (
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS Row, *
FROM tblFiles ) AS tbl WHERE Row >= '
+ CONVERT(varchar(9), #StartIdx) + ' AND
Row <= ' + CONVERT(varchar(9), #EndIdx) + ' AND
FileName = #file_name'
EXEC sp_executesql #SQL
SET #SQL = 'SELECT #TotalRows=COUNT(*) FROM tblFiles'
EXEC sp_executesql
#query = #SQL,
#params = N'#TotalRows INT OUTPUT',
#TotalRows = #TotalRows OUTPUT,
#file_name = #f_name
END

Related

How to use dynamic SQL string?

Instead of this:
-- Method call
SELECT #FunctionResult = DWH_Staging.adm.SalesPlanExists(#Year, #Month, #CountryID, #Type)
I want to use something like this:
DECLARE
#TestedDatabase = 'DWH_Staging',
#TestedSchema = 'adm',
#TestedObject = 'SalesPlanExists'
DECLARE #sql NVARHCAR(4000) = '#TestedDatabase+'.'+#TestedSchema+'.'+#TestedObject (#Year, #Month, #CountryID, #Type)'
-- Method call
SELECT #FunctionResult = #sql
Hints would be appreciated.
Below is a parameterized SQL example, guessing at your data types:
DECLARE
#TestedDatabase sysname = 'DWH_Staging'
,#TestedSchema sysname = 'adm'
,#TestedObject sysname = 'SalesPlanExists'
,#FunctionResult int
,#Year int
,#Month int
,#CountryID int
,#Type int;
DECLARE #sql nvarchar(MAX) = N'SELECT #FunctionResult = '
+QUOTENAME(#TestedDatabase)
+N'.'
+QUOTENAME(#TestedSchema)
+N'.'
+QUOTENAME(#TestedObject)
+ N'(#Year, #Month, #CountryID, #Type)';
SELECT #sql
-- Method call
EXECUTE sp_executesql
#sql
,N'#FunctionResult int OUTPUT
,#Year int
,#Month int
,#CountryID int
,#Type int'
,#FunctionResult = #FunctionResult OUTPUT
,#Year = #Year
,#Month = #Month
,#CountryID = #CountryID
,#Type = #Type;
What you can do is to set a template for the query, and replace the string while execution:
DECLARE #sql NVARHCAR(4000) = '{DATABASENAME}.{SCHEMANAME}.{OBJECTNAME} (' + #Year + ', ' + #Month + ', ' + #CountryID + ', ' + #Type + ')'
SET #SQL_SCRIPT = REPLACE(#sql, '{DATABASENAME}', #DBNAME)
and then, execute it:
EXECUTE (#SQL_SCRIPT)

Dynamic query variable error

I have a table #months as below
MONTH_ID FISCAL_YEAR_MONTH MIN_DATE MAX_DATE
1 FSA201510 20151001 20151031
2 FSA201511 20151101 20151130
3 FSA201512 20151201 20151204
I am using below dynamic query to update a column SCCount in table mastercount(has 3 rows)-
DECLARE #sql VARCHAR(8000), #fym varchar(6)
DECLARE #I INT, #ROWS INT
SET #ROWS=(SELECT count(*) from #MONTHS)
SET #I=1
WHILE #I<=#ROWS
BEGIN
SET #fym=(SELECT RIGHT(FISCAL_YEAR_MONTH,6) from #MONTHS where month_id=#I)
SET #sql = 'UPDATE mastercount'
SET #sql += ' SET SCCount = (SELECT count(*) from '
SET #sql += ' dw_extract.dbo.dw_fsa_' + cast(#fym as varchar(6))+ ') WHERE row=#I'
EXEC (#sql)
SET #I=#I+1
END
This gives an error Must declare the scalar variable "#I".
Why is this happening?
You need to change this
SET #sql += ' dw_extract.dbo.dw_fsa_' + cast(#fym as varchar(6))+ ') WHERE row=#I'
to this
SET #sql += ' dw_extract.dbo.dw_fsa_' + cast(#fym as varchar(6))+ ') WHERE row=' + CAST(#I AS NVARCHAR(10))
That's because #I is not recognized by your dynamic query. You should parameterized #I instead and use sp_executesql to run your query:
DECLARE #sql NVARCHAR(8000), #fym VARCHAR(6)
DECLARE #I INT, #ROWS INT
SET #ROWS = (SELECT COUNT(*) FROM #MONTHS)
SET #I = 1
WHILE #I <= #ROWS
BEGIN
SET #fym = (SELECT RIGHT(FISCAL_YEAR_MONTH,6) FROM #MONTHS WHERE month_id = #I)
SET #sql = N'UPDATE mastercount'
SET #sql += N' SET SCCount = (SELECT count(*) from '
SET #sql += N' dw_extract.dbo.dw_fsa_' + cast(#fym as varchar(6))+ N') WHERE row=#I'
EXEC sp_executesql #sql, N'#I INT', #I
SET #I = #I + 1
END

Msg 137, Level 15, State 2, Line 29 Must declare the scalar variable "#ACTIVE_STATUS"

ALTER PROCEDURE [dbo].[S_EDIT_USER] (#DSA_CODE VARCHAR(10),
#REQUESTOR_DEPT VARCHAR(40),
#ACTIVE_STATUS INT,
#MAKER_ID VARCHAR(10),
#MAKER_IP VARCHAR(20),
#ERROR_CODE INT OUTPUT)
AS
BEGIN
DECLARE #CNT INT;
DECLARE #SQL NVARCHAR(MAX);
SELECT #CNT = COUNT(*)
FROM TMAS_UAM_USER_TMP
WHERE DSA_CODE = #DSA_CODE;
IF #CNT > 0
SET #ERROR_CODE = 1;
ELSE
SET #ERROR_CODE = 0;
IF #REQUESTOR_DEPT = 'N'
SET #REQUESTOR_DEPT = '';
ELSE
SET #REQUESTOR_DEPT = #REQUESTOR_DEPT;
PRINT #REQUESTOR_DEPT;
IF #ERROR_CODE = 0
SET #SQL = 'INSERT INTO TMAS_UAM_USER_TMP (
DSA_CODE
,DSA_NAME
,DSA_CITY
,DSA_PRODUCT
,DSA_PHNO
,DSA_MOBNO
,DSA_RQSTR
,DSA_RQSTR_DEPT
,GROUP_ID
,ACTIVE_STATUS
,REQ_TYPE
,LAST_LOGED_IN
,CREATED_ID
,CREATED_IP
,CREATED_DATE
,MAKER_ID
,MAKER_IP
,MAKER_DATE
) SELECT DSA_COD
,DSA_NAM
,DSA_CTY
,PRODUCT
,DSA_PHO
,DSA_MOB
,REQUESTOR
,' + #REQUESTOR_DEPT + '
,GROUP_ID
,#ACTIVE_STATUS
,1
,LAST_LOG_DAT
,CREATED_ID
,CREATED_IP
,CREATED_DATE
,' + #MAKER_ID + '
,' + #MAKER_IP + '
,GETDATE()
FROM DSA_MST WHERE DSA_COD = ' + #DSA_CODE + ' and ';
IF #REQUESTOR_DEPT = 'N'
BEGIN
SET #SQL = #SQL + 'REQUESTOR_DEPT is null';
PRINT( 'If Query' + #SQL );
END
ELSE
BEGIN
SET #SQL = #SQL + 'REQUESTOR_DEPT = ''' + #REQUESTOR_DEPT + '''';
PRINT( 'Else Query' + #SQL );
END
EXECUTE (#SQL);
RETURN #ERROR_CODE;
END
The outer variables and parameters are not in scope for your EXECUTE (#SQL);
You need to use sp_executesql instead and pass them in as parameters.
Also you should read up on SQL injection. You might be vulnerable if parameters such as #REQUESTOR_DEPT originate from untrusted sources such as user input as you are just concatenating them straight into the query.

incorrect syntax near '*'

I was trying to execute one of my Stored procedure but i am getting an syntax error and i am unable to understand why.
here is the sproc:
ALTER PROCEDURE [dbo].[HotlinePlusAdministration_ArticleMigrator]
#ArticleKey AS INT,
--#CategoryID AS INT,
--#Title AS Varchar(200),
--#ArticleDate AS datetime,
#DestLinkServer AS VARCHAR(50),
#UserID AS VARCHAR(8),
#ReturnMsg AS VARCHAR(1000) OUTPUT
AS
BEGIN
DECLARE #Query AS NVARCHAR(4000)
DECLARE #Log AS VARCHAR(8000)
DECLARE #ArticleID as int
DECLARE #NewArticleID as int
DECLARE #ArticleKeyExists as int
DECLARE #Title as varchar(200)
DECLARE #CategoryID as INT
DECLARE #ArticleDate as varchar(30)
DECLARE #ParmDefinition nvarchar(500);
SET XACT_ABORT ON -- Required for nested transaction
BEGIN TRAN
-- Check if ArticleID exists in Destination Server
SET #Query = N' SELECT #ArticleKeyExists = COUNT(*)
FROM ' + #DestLinkServer + '.HL2_61.dbo.Article' + ' where ArticleKey = ' + str(#ArticleKey)
SET #ParmDefinition = N'#ArticleKey int, #ArticleKeyExists int OUTPUT';
EXECUTE sp_executesql #Query , #ParmDefinition, #ArticleKey , #ArticleKeyExists OUTPUT;
IF ##ERROR <> 0
BEGIN
ROLLBACK TRANSACTION
SET #ReturnMsg = #Log + '<span style="color:red;">ERROR: <br></span>'
RETURN -1
END
--Delete existing Articles for select page
set #Query = 'DELETE FROM ' + #DestLinkServer +
'.HL2_61.dbo.Article ' +
'WHERE ArticleKey = ' + CONVERT(VARCHAR, #ArticleKey)
--'WHERE CategoryID = ' + CONVERT(VARCHAR, #CategoryID) + ' and Title = ''' + #Title + ''' and ArticleDate = ''' + #ArticleDate + ''''
Print #Query
EXEC(#Query)
when i am trying to execute it i am getting an error here:
SELECT #ArticleKeyExists = COUNT(*)
FROM BRWSQLDC.HL2_61.dbo.Article where ArticleKey = 1591276581
Can some body please help me on this,
Thanks.
SET #ArticleKeyExists = (SELECT COUNT(*) FROM BRWSQLDC.HL2_61.dbo.Article where ArticleKey = 1591276581)

Dynamic sql and spexecutesql behavior

I have a table like
c1 c2 c3 c4
-----------------
2 1 7 13
9 2 8 14
1 3 9 15
5 4 10 16
2 5 11 17
11 6 12 18
As in general I would not know the number of columns (in the code #d here 4) to get a string in the form:
2,9,1,5,2,11, 1,2,3,4,5,6, 7,8,9,10,11,12, 13,14,15,16,17,18
To do so I am doing:
DECLARE #d INT
,#counterI INT
,#template AS nvarchar(max)
SET #d = 4;
SET #counterI = 1;
Set #template = 'SELECT STUFF(
( SELECT '','' + CAST([col] AS VARCHAR) FROM (';
WHILE (#counterI < #d) BEGIN
SET #template += ' SELECT [c'+CAST(#counterI-1 AS VARCHAR)+'] AS col FROM [MyTable] UNION ALL ';
SET #counterI = #counterI + 1;
END
Set #template += ' SELECT [c'+CAST(#counterI-1 AS VARCHAR)+'] AS col FROM [MyTable] '
Set #template += ') alldata FOR XML PATH('''') ) , 1 , 1 , '''' )';
declare #CommaString varchar(max)
set #CommaString = ''
exec sp_executesql #template, N'#CommaString varchar(max) out', #CommaString out
So if I do
select #CommaString;
Why is not #CommaString at the moment of selecting it returning the string if when doing the sp_executesql it is printing it right?
I may be missing something about how sp_executesql works, but don't you need something like 'SELECT #CommaString = ...' in #template, so that it assigns the comma string to the out parameter?
Just to clarify, I think you need something like:
DECLARE #d INT
,#counterI INT
,#template AS nvarchar(max)
SET #d = 4;
SET #counterI = 1;
Set #template = 'SELECT #CommaString = STUFF(
( SELECT '','' + CAST([col] AS VARCHAR) FROM (';
WHILE (#counterI < #d) BEGIN
SET #template += ' SELECT [c'+CAST(#counterI-1 AS VARCHAR)+'] AS col FROM [MyTable] UNION ALL ';
SET #counterI = #counterI + 1;
END
Set #template += ' SELECT [c'+CAST(#counterI-1 AS VARCHAR)+'] AS col FROM [MyTable] '
Set #template += ') alldata FOR XML PATH('''') ) , 1 , 1 , '''' )';
declare #CommaString varchar(max)
set #CommaString = ''
exec sp_executesql #template, N'#CommaString varchar(max) out', #CommaString = #CommaString out
As a simpler example, something like this is perhaps easier to read/see what I mean:
declare #CommaString varchar(max)
set #CommaString = ''
exec sp_executesql 'SELECT #CommaString = ''1,2,3''', '#CommaString varchar(max) out', #CommaString = #CommaString out
Incidentally, I've usually seen this kind of thing for string concatenation:
DECLARE #MyString varchar(max)
SET #MyString = ''
SELECT #MyString = #MyString + ',' + MyColumn
FROM MyTable

Resources