Error coming while creating UDF in Sql Server 2005 - sql-server-2005

Does anyone know what's wrong with this code block.
CREATE FUNCTION [dbo].[udfGetPoint]
(
#UserID INT,
#SqlCountry VARCHAR(1000)
)
RETURNS INT
AS
BEGIN
DECLARE #Points INT
SET #Points = 1
DECLARE #RecordCount sysname
IF #SqlCountry <> ''
BEGIN
EXEC sp_executesql
N'SELECT #DynamicCount = COUNT(UserID) FROM Country WHERE UserID = '+#UserID+' AND LCValues IN (' + #SqlCountry + ')'
,N'#DynamicCount sysname OUTPUT'
,#RecordCount OUTPUT
IF #RecordCount > 0
SET #Points = #Points + 1
END
RETURN #Points
END
If i execute this i got following error:
Msg 102, Level 15, State 1, Procedure udfGetPoint, Line 15
Incorrect syntax near '+'.

You can't concatenate in the parameter setting of a stored procedure.
DECLARE #sql varchar(2000)
SET #SQL = 'SELECT #DynamicCount = COUNT(UserID) FROM Country WHERE UserID = '+#UserID+' AND LCValues IN (' + #SqlCountry + ')'
EXEC sp_executesql
#SQL
,N'#DynamicCount sysname OUTPUT'
,#RecordCount OUTPUT

Related

Getting OUTPUT from Nested Dynamic SQL with a Remote Server

I am trying to execute some logic on a remote server using dynamic SQL, but when I set the dynamic SQL and try to call it nothing happens.. If I call the execution without making the execution dynamic it works without issue.
Not sure if what I am trying to do is allowed when passing OUTPUT values but figured I would see if anyone has any thoughts
DECLARE #sqlserver NVARCHAR(MAX) = ''
DECLARE #DBName NVARCHAR(MAX) = ''
DECLARE #parms NVARCHAR(MAX) = N'#output INT OUT', #output INT, #sql NVARCHAR(MAX) = '
;WITH DuplicateStatusCodes AS (
SELECT CodeTypeID FROM EDDSDBO.Code WHERE Name = ''Master'' OR Name = ''Unique'' OR Name = ''Duplicate''
)
SELECT ROW_NUMBER() OVER (ORDER BY CodeTypeID) RN, CodeTypeID INTO #temp
FROM DuplicateStatusCodes
GROUP BY CodeTypeID
HAVING COUNT(CodeTypeID) = 3
DECLARE #count INT = (SELECT COUNT(1) FROM #temp)
DECLARE #ctr INT = 1;
IF #count > 0
BEGIN
WHILE #ctr <= #count BEGIN
DECLARE #parms NVARCHAR(MAX) = N''#inneroutput INT OUT'';
DECLARE #inneroutput INT
DECLARE #codeartifact INT = (SELECT CodeTypeID FROM #temp WHERE RN <= 1 * #ctr and RN > 1 * (#ctr - 1))
DECLARE #duplicatestatuscheck NVARCHAR(MAX) = ''SELECT #inneroutput = COUNT(1) FROM eddsdbo.codeartifact_''+CAST(#codeartifact AS VARCHAR)+''''
EXEC sys.sp_executesql #duplicatestatuscheck, #parms, #inneroutput OUT
SELECT #output = #inneroutput
IF #inneroutput > 0
BREAK;
SET #ctr = #ctr + 1;
END
END
ELSE
BEGIN
SELECT #output = ''0''
END
'
DECLARE #linksql NVARCHAR(MAX) = '
DECLARE #sql NVARCHAR(MAX)
DECLARE #parms NVARCHAR(MAX) = N''#output INT OUT''
EXEC '+QUOTENAME(#sqlserver)+'.'+QUOTENAME(#DBName)+'.sys.sp_executesql #sql, #parms, #output = #output OUT'
--This does not work
EXEC sp_executesql #linksql, #parms, #output = #output
PRINT #output
--This works fine
EXEC [RemoteServerName].[DatabaseName].sys.sp_executesql #sql, #parms, #output = #output OUT ```
Appreciate any help
you would need to use OPENROWSET. Something like this:
DECLARE #ServerName VARCHAR(255) = '...'
,#DatabaseName VARCHAR(255) = '...'
,#Pwd VARCHAR(255) = '...'
,#UID VARCHAR(255) = '...'
,#Name VARCHAR(255) = 'Master'
DECLARE #connect varchar(max) = '''Server=' + #ServerName + ';database=' + #DatabaseName + ';Uid=' + #UID + ';Pwd=' + #Pwd + ';'''
declare #sqlstring varchar(max) = 'SET ANSI_NULLS OFF; SET ANSI_WARNINGS OFF;
SELECT CodeTypeID FROM EDDSDBO.Code WHERE Name = ''''' + #Name + ''''' '
declare #TheExecutableStr varchar(max) = '
SELECT *
FROM OPENROWSET(''SQLNCLI'', ' + #connect + ',
''' + #sqlstring + ''')'
SELECT #TheExecutableStr
--EXEC(#TheExecutableStr)
Please note you have to count single quote very diligently, hence SELECT #TheExecutableStr. It is for debugging purposes. You can view the query to be executed and actually copy/paste and execute before uncommenting last statement.
Hope it helps.
just noticed, you have sys.sp_executesql within sys.sp_executesql which might be problematic. you might need to find a way to refactor the code.

Putting 3 inputs to the Stored Procedure in SQL Server

There is a Student Table, with the column of ID and Name. However,
wanted to use the parameters in the Stored Procedure to get:
select * from Student where ID = value;
While, I used this code. Could not get the outpur. Moreover, I have
got this error message:
select * from [Student] where ID = 2 Msg 203, Level 16, State 2,
Procedure FindTblName, Line 11 [Batch Start Line 28] The name 'select
* from [Student] where ID = 2' is not a valid identifier.
create procedure FindTblName
#tblName varchar(100),
#IDName varchar(10),
#IDValue int
as
begin
declare #sql varchar(max)
set #sql = 'select * from '+ QUOTENAME(#tblName) + ' where ' + #IDName + ' = ' + convert(nvarchar(2),#IDValue)
print #sql
exec #sql
end
exec FindTblName #tblName = Student, #IDName = ID, #IDValue = 2;
IF you must do something like this then properly quote your object names, and parametrise your parameters. Then pass your object names as a nvarchar, not an an unknown "object" type:
CREATE PROC dbo.FindTblName #TblName sysname , #IDName sysname, #IDValue int AS
BEGIN
DECLARE #SQL nvarchar(MAX);
SET #SQL = N'SELECT * FROM dbo.' + QUOTENAME(#TblName) + N' WHERE ' + QUOTENAME(#IDName) + N' = #IDValue;';
EXEC sp_executesql #SQL, N'#IDValue int', #IDValue;
END;
GO
EXEC dbo.FindTblName #TblName = N'Student', #IDName = N'ID', #IDValue = 2;

Adding LOOP to my Stored PROCEDURE

Below is a sample of my stored procedure, can someone help me how I have the following error:
'Msg 22027, Level 15, State 1, Line 0
Usage: EXECUTE xp_fileexist <filename> [, <file_exists INT> OUTPUT]
Msg 245, Level 16, State 1, Procedure TextImpoted01, Line 39
Conversion failed when converting the varchar value 'No' to data type int.'
USE [test]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[TextImpoted01]
AS
SET NOCOUNT ON;
DECLARE #SQL NVARCHAR(100)
SELECT TOP (1) #SQL = total FROM DealCounter
DECLARE #path NVARCHAR(max)
SET #path = 'c:\temp\TextImpoted'+ #SQL + '.txt'
DECLARE #UpdateSQL NVARCHAR(100)
SET #UpdateSQL = N'UPDATE DealCounter SET total = total + 1'
DECLARE #LOOP NVARCHAR(100)
SELECT TOP (1) #LOOP = total FROM DealCounter
DECLARE #bulk_cmd NVARCHAR(max);
DECLARE #isExists INT
WHILE #SQL <= #LOOP + 1000
BEGIN
SET #path = 'c:\temp\TextImpoted'+ #SQL + '.txt'
exec master.dbo.xp_fileexist #path ,isExists out
SELECT case #isExists
when 1 then 'Yes'
else 'No'
end as isExists
if #isExists = 'No'
BREAK
else
SET #bulk_cmd = 'BULK INSERT TextImpoted FROM '''+ #path + '''
WITH
(
FIELDTERMINATOR = ' + ''';''' + ', ROWTERMINATOR = ' + '''\n'''+ ')';
EXEC sp_executesql #bulk_cmd
EXECUTE sp_executesql #UpdateSQL;
set #SQL = #SQL + 1;
END
First: The output variable from exec master.dbo.xp_fileexist #path ,isExists out
lacks an # sign and should be exec master.dbo.xp_fileexist #path , #isExists out.
Second: The error comes from trying to compare the INT variable #isExists with a char value in the case statement.
The case block is redundant however and could be replaced with:
EXEC master.dbo.xp_fileexist #path ,#isExists OUT
IF (#isExists = 1)
BEGIN
(... your logic here ... )
END
Your problem actually doesn't concerns loops.
You are declaring #isExists as integer here:
DECLARE #isExists INT
And here you're comparing it with varchar value.
if #isExists = 'No'
This produces error you've seen.
Also note this line of code:
exec master.dbo.xp_fileexist #path ,isExists out
It is definitely should be #isExists here and you're missing #

How to store values from a dynamic sql into a variable?

I am trying to store next value for the sequence into a variable and the statement is called in a dynamic sql as below.
DECLARE #Sequence VARCHAR(100) = 'IMEIIDLookUP'
DECLARE #NextVal INT
DECLARE #SQL NVARCHAR(4000)
SELECT #SQL = 'SELECT (NEXT VALUE FOR [dbo].' + QUOTENAME(#Sequence) + ')'
SELECT #NextVal = EXEC (#SQL)
SELECT #NextVal
The above query fails with error
Incorrect syntax near the keyword 'EXEC'.
What would be the correct syntax here? Having said that, I cannot avoid using dynamic sql.
Use sp_executesql:
DECLARE #Sequence VARCHAR(100) = 'IMEIIDLookUP';
DECLARE #NextVal INT;
DECLARE #SQL NVARCHAR(4000);
SELECT #SQL = 'SELECT #NextVal = (NEXT VALUE FOR [dbo].' + QUOTENAME(#Sequence) + ')';
exec sp_executesql #SQL, N'#NextVal int output', #NextVal = #NextVal output;
SELECT #NextVal;

Procedure error "Must declare the table"

I have a block code to create a procedure:
CREATE PROCEDURE GetTableinfomation
#table nvarchar(50),
#column nvarchar(50),
#valuedk nvarchar(50)
AS
BEGIN
SELECT *
FROM #table
WHERE #column = #valuedk
END
and I have an error.
Msg 1087, Level 15, State 2, Procedure GetTableinfomation, Line 7
Must declare the table variable "#tenbang".
Why?
You cannot use SQL parameters for table names and columns, only for variables.
You could get around this by using dynamic SQL:
DECLARE #SQL nvarchar(4000)
DECLARE #PARAMS nvarchar(4000)
SET #SQL = 'SELECT * FROM '
+ QUOTENAME(#table,'"') + ' WHERE '
+ QUOTENAME(#column,'"') + '= #param1'
SET #PARAMS = '#param1 nvarchar(50)'
EXEC sp_executesql #SQL, #PARAMS, #param1=#valuedk
See the documentation on sp_executesql for more information:
http://msdn.microsoft.com/en-us/library/ms188001.aspx