Use null result of exec sp_execute - sql-server

I have some dynamic SQL that I use to see if a certain property for a certain client is in a table. If so, it will return the value, if not, it will return null. However, I would like it to return a default value if the property is not found.
The table:
CREATE TABLE [test].[customers](
[customer] [nvarchar](256) NULL,
[key_name] [nvarchar](256) NULL,
[key_value] [nvarchar](256) NULL
)
GO
INSERT INTO [test].[customers]
([customer]
,[key_name]
,[key_value])
VALUES
('JohnDoe'
,'periodlength'
,'3')
GO
The Dynamic SQL:
declare #customer as nvarchar(256) = 'JohnDoe'
declare #table as nvarchar(256) = 'test.customers'
declare #sql as nvarchar(4000)
set #sql = 'select [key_value] from ' + #table + ' where [key_name]= ''periodlength'' and customer= ''' + #customer + ''''
exec sp_executesql #sql
So when Qqerying for John Doe you get result 3 which is perfect. However, I would like to reurn 1 for Jane Doe. So I was thinking along the lines
IF exec sp_executesql #sql IS NULL 1 ELSE exec sp_executesql #sql
but that doesn't work.
How to change my dynamic query so that is returns a default value if the property is not found?

Could you try the following query but this usage only return a single value;
declare #customer as nvarchar(256) = 'JohnDoe'
declare #table as nvarchar(256) = 'test.customers'
DECLARE #ValReturn nvarchar(50)
declare #sql as nvarchar(4000)
set #sql = 'select #ValOutPut=[key_value] from ' + #table + ' where [key_name]= ''periodlength'' and customer= ''' + #customer + ''''
exec sp_executesql #sql , N'#ValOutPut nvarchar(25) OUTPUT' ,#ValOutPut = #ValReturn OUTPUT
BEGIN
IF #ValReturn IS NULL
SELECT NULL
ELSE
SELECT #ValReturn
END

Related

Loop with dynamic table name and where clause stored procedure

I am trying to update records and insert their audits to audit table.
For this purpose stored procedure waiting for above variables.
#m_obj_id INT,
#m_obj_code NVARCHAR(250),
#m_f_code NVARCHAR(250),
#m_nv NVARCHAR(4000),
#m_last_mod_by INTEGER,
#table_name SYSNAME,
--#where_clause NVARCHAR(4000)
Stored procedure formatting these variables as;
UPDATE #table_name SET #m_f_code=#m_nv WHERE id=#m_obj_id
And at last part inserting into audit.
I can use it with doing SELECT CONCAT and copying all the rows then execute.
But my goal is here not expecting #m_obj_id from user and replace it #where_clause. And use this #where_clause to get ids inside.
So far I tried;
DECLARE #Sql NVARCHAR(MAX)
DECLARE #RecordId int = 0
BEGIN
SET #SQL = N'
SELECT #RecordId = MIN(id)
FROM ' + #table_name + '
WHERE id > #RecordId AND (' + #where_clause + ')
IF #RecordId IS NULL BREAK
SET #m_obj_id = #RecordId'
Exec sp_executesql #sql
But couldnt get far with it.
Then I tried something like;
DECLARE #RowsToProcess int
DECLARE #CurrentRow int
DECLARE #SelectCol1 int
DECLARE #sql NVARCHAR(MAX)
SET #sql = N'
DECLARE #table1 TABLE (RowID int not null primary key identity(1,1), col1 int )
INSERT into #table1 (col1) SELECT id FROM ' + #table_name + ' Where ' + #where_clause + '
SET #RowsToProcess=##ROWCOUNT'
EXEC sp_executesql #sql,
N'#RowsToProcess INT OUTPUT', #RowsToProcess OUTPUT
SET #CurrentRow=0
WHILE #CurrentRow<#RowsToProcess
BEGIN
SET #CurrentRow=#CurrentRow+1
DECLARE #sql2 NVARCHAR(MAX)
SET #sql2 = N'
SET #m_obj_id =
(SELECT col1
FROM #table1
WHERE RowID=#CurrentRow)'
EXEC sp_executesql #sql2
But still no luck.
Can I achieve this any how? I am trying to do this for more than it should be.
Thanks all.
The non-dynamic way to implement dynamic filtering on sql is the following:
where id=#m_obj_id or #m_obj_id is null
For a LOT of more details on how to choose between dynamic and non-dynamic sql on this, I recommend this article by Erland Sommarskog
I found a solution. Thanks everyone for responding.
I used a temp table like
DECLARE #RowsToProcess INTEGER
DECLARE #CurrentRow INTEGER
DECLARE #SelectCol1 INTEGER
CREATE TABLE #tmp (RowID INTEGER NOT NULL PRIMARY KEY IDENTITY(1,1), col1 int)
DECLARE #sql NVARCHAR(MAX)
SET #sql = N'
INSERT into #tmp (col1) SELECT id FROM ' + #table_name + ' Where ' + #where_clause + '
SET #RowsToProcess=##ROWCOUNT'
INSERT INTO #tmp
EXEC sp_executesql #sql,
N'#RowsToProcess INT OUTPUT', #RowsToProcess OUTPUT
SET #CurrentRow=0
WHILE #CurrentRow<#RowsToProcess
BEGIN
SET #CurrentRow=#CurrentRow+1
SET #m_obj_id =
(SELECT col1
FROM #tmp
WHERE RowID=#CurrentRow)
Do stuff....

Execute dynamic query that executes another stored procedure

I have a query like this:
DECLARE #TaskId UNIQUEIDENTIFIER
DECLARE #TaskName VARCHAR(255) = 'MasterSet'
DECLARE #sql NVARCHAR(MAX)
DECLARE #StartingDateTask DATETIME2 = (SELECT TOP 1 [Date]
FROM [TaskStatusAudit]
WHERE [TaskId] = 'A1FDFC16-904D-4560-B19D-5E7D4FEB1C2B'
AND [TaskStatusName] = 'IN-PROGRESS')
DECLARE #EndingDateTask DATETIME2 = (SELECT TOP 1 [Date]
FROM [TaskStatusAudit]
WHERE [TaskId] = 'A1FDFC16-904D-4560-B19D-5E7D4FEB1C2B'
AND [TaskStatusName] = 'COMPLETED')
SET #sql = N'SELECT dbo.TotalMinuteRange(#StartingDateTask,#EndingDateTask) as ' + quotename(#TaskName) + N''
EXEC sp_executesql #sql
Problem is when I execute it I get this error:
Must declare the scalar variable "#StartingDateTask".
Any ideas why I getting that if I declare my variable correctly? Regards
When executing sp_executesql you need to declare and pass the variables to sp_executesql something like..
SET #sql = N'SELECT dbo.TotalMinuteRange(#StartingDateTask,#EndingDateTask) as '
+ quotename(#TaskName) + N''
exec sp_executesql #sql
, N'#StartingDateTask DATETIME2 , #EndingDateTask DATETIME2'
, #StartingDateTask
, #EndingDateTask
Second parameter is the variable declaration parameter followed by the actual variables separately.
You can also do like taking a parameters variable and assign it.
declare #params nvarchar(100)
set #params='#StartingDateTask DATETIME2,#EndingDateTask DATETIME2'
SET #sql = N'SELECT dbo.TotalMinuteRange(#StartingDateTask,#EndingDateTask) as '
+ quotename(#TaskName) + N''
exec sp_executesql #sql
, #params
, #StartingDateTask
, #EndingDateTask

Stored procedure with table name and values as parameters

I have problems for insert values with a stored procedure with values as parameters and table name too. this is part of my table:
My table:
CREATE TABLE [dbo].[INGRESOLOTEMP_100]
(
[CLIENTE_CODIGO] [SMALLINT] NOT NULL,
[CAJA_CODIGO] [nvarchar](20) NULL,
[CAJA_NUMERO] [SMALLINT] NOT NULL,
)
My stored procedure:
CREATE PROCEDURE [dbo].[SP_LOT_INSERTLOTEMP]
#IDENT_TABLA NVARCHAR(10),
#CLIENTE_CODIGO SMALLINT,
#CAJA_CODIGO NVARCHAR(15),
#CAJA_NUMERO SMALLINT
AS
DECLARE #NOMBRE_TABLA NVARCHAR(40)
SELECT
#NOMBRE_TABLA = 'INGRESOLOTEMP_' + CONVERT(VARCHAR(100), #IDENT_TABLA)
SELECT
#CAJA_CODIGO = CONVERT(VARCHAR(20), #CAJA_CODIGO)
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'INSERT into dbo.' + quotename(#NOMBRE_TABLA) +
' (CLIENTE_CODIGO, CAJA_CODIGO, CAJA_NUMERO) VALUES (' +
CONVERT(VARCHAR(20),#CLIENTE_CODIGO) + ',' + #CAJA_CODIGO + ',' +
CONVERT(VARCHAR(20),#CAJA_NUMERO) +
')'
EXEC sp_executesql #SQL
My table name is formed by a table name + an Id (every user has one)
But the problem is when I execute the stored procedure:
SP_LOT_INSERTLOTEMP 100, 123, 'uio123', 1
I have an error in SQL with value: 'uio123'
But if I execute:
SP_LOT_INSERTLOTEMP 100, 123, 80, 1
The insert is perfect, The problem is that I need insert numeric and text values, even date time values too. I realized varchar conversions in the stored procedure, but I don't get it yet.
Anyone, have an Idea?
Please I hope you can help me.
Gregg, Giorgi...
Thanks, I followed your advices, I think I get it:
ALTER PROCEDURE [dbo].[SP_LOT_INSERTLOTEMP]
#IDENT_TABLA NVARCHAR(10),
#CLIENTE_CODIGO SMALLINT,
#CAJA_CODIGO NVARCHAR(15),
#CAJA_NUMERO SMALLINT
AS
BEGIN
DECLARE #NOMBRE_TABLA NVARCHAR(40)
SELECT #NOMBRE_TABLA = 'INGRESOLOTEMP_' + CONVERT(VARCHAR(100),#IDENT_TABLA)
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'INSERT into dbo.' + #NOMBRE_TABLA
SET #SQL += '(CLIENTE_CODIGO, CAJA_CODIGO, CAJA_NUMERO) VALUES ('
SET #SQL += CONVERT(VARCHAR(20), #CLIENTE_CODIGO) + ', '
SET #SQL += '''' + CONVERT(VARCHAR(20), #CAJA_CODIGO) + ''', '
SET #SQL += CONVERT(VARCHAR(20), #CAJA_NUMERO) + ')'
DECLARE #ParmDefinition nvarchar(500)
SET #ParmDefinition = '#IDENT_TABLA NVARCHAR(10), #CLIENTE_CODIGO SMALLINT, #CAJA_CODIGO NVARCHAR(15), #CAJA_NUMERO SMALLINT'
SELECT #sql
PRINT #sql
EXEC sp_executesql #SQL, #ParmDefinition, #IDENT_TABLA, #CLIENTE_CODIGO, #CAJA_CODIGO, #CAJA_NUMERO
END
And when I print what execution contains:
EXEC [SP_LOT_INSERTLOTEMP] 100, 123, 'UIO123', 6
I have this:
INSERT into dbo.INGRESOLOTEMP_100(CLIENTE_CODIGO, CAJA_CODIGO, CAJA_NUMERO) VALUES (123, 'UIO123', 6)
I will continue, If I have any question, I hope somebody or you, can help me.
Thanks.
The problem is in varchar column. Notice the generated statements for
EXEC SP_LOT_INSERTLOTEMP 100, 123, 'uio123', 1
EXEC SP_LOT_INSERTLOTEMP 100, 123, 80, 1
INSERT into dbo.[INGRESOLOTEMP_100] (CLIENTE_CODIGO, CAJA_CODIGO, CAJA_NUMERO) VALUES (123,uio123,1)
INSERT into dbo.[INGRESOLOTEMP_100] (CLIENTE_CODIGO, CAJA_CODIGO, CAJA_NUMERO) VALUES (123,80,1)
Try uncommenting --PRINT #SQL and see yourself the resulting statements.
You should provide additional quotes. Try this:
ALTER PROCEDURE [dbo].[SP_LOT_INSERTLOTEMP]
#IDENT_TABLA NVARCHAR(10),
#CLIENTE_CODIGO SMALLINT,
#CAJA_CODIGO NVARCHAR(15),
#CAJA_NUMERO SMALLINT
AS
DECLARE #NOMBRE_TABLA NVARCHAR(40)
SELECT #NOMBRE_TABLA = 'INGRESOLOTEMP_' + CONVERT(VARCHAR(100),#IDENT_TABLA)
SELECT #CAJA_CODIGO = CONVERT(VARCHAR(20), #CAJA_CODIGO)
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'INSERT into dbo.' + quotename(#NOMBRE_TABLA) +
' (CLIENTE_CODIGO, CAJA_CODIGO, CAJA_NUMERO) VALUES (' +
+ CONVERT(VARCHAR(20),#CLIENTE_CODIGO) +','''/*changes here*/ + #CAJA_CODIGO + ''','/*changes here*/ +
CONVERT(VARCHAR(20),#CAJA_NUMERO) +
')'
--PRINT #SQL
EXEC sp_executesql #SQL
Several changes needed to be made to your procedure; see below:
ALTER PROCEDURE [dbo].[SP_LOT_INSERTLOTEMP]
#IDENT_TABLA NVARCHAR(10),
#CLIENTE_CODIGO SMALLINT,
#CAJA_CODIGO NVARCHAR(15),
#CAJA_NUMERO SMALLINT
AS
BEGIN
DECLARE #NOMBRE_TABLA NVARCHAR(40)
SELECT #NOMBRE_TABLA = 'INGRESOLOTEMP_' + CONVERT(VARCHAR(100),#IDENT_TABLA)
SELECT #CAJA_CODIGO = CONVERT(VARCHAR(20), #CAJA_CODIGO)
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'INSERT into dbo.' + #NOMBRE_TABLA
SET #SQL += '(CLIENTE_CODIGO, CAJA_CODIGO, CAJA_NUMERO)
VALUES (#CLIENTE_CODIGO, #CAJA_CODIGO, #CAJA_NUMERO)'
DECLARE #ParmDefinition nvarchar(500)
SET #ParmDefinition = '#IDENT_TABLA NVARCHAR(10), #CLIENTE_CODIGO SMALLINT, #CAJA_CODIGO NVARCHAR(15), #CAJA_NUMERO SMALLINT'
SELECT #sql
EXEC sp_executesql #SQL, #ParmDefinition, #IDENT_TABLA, #CLIENTE_CODIGO, #CAJA_CODIGO, #CAJA_NUMERO
END

Table Name Variable in select statement in sql server

I want to use tablename variable in select statement, but it is giving error
- Must declare the table variable "#table"
alter PROCEDURE testTblName
(
#id int,
#name varchar(50)
)
AS
BEGIN
declare #table varchar(50)
declare #add varchar(150)
set #table = 'DBTest..testMaster'
select #add = address from #table where id=#id and name=#name
END
This is a snap shot of my code
You need to use dynamic sql for this:
alter PROCEDURE testTblName
(
#id int,
#name varchar(50)
)
AS
BEGIN
declare #table varchar(50)
declare #add varchar(150)
set #table = 'DBTest..testMaster'
DECLARE #sql NVARCHAR(MAX)
SELECT #sql = 'select #add = address from ' + #table + ' where id= ' + #id + ' and name= ' + #name
EXEC sp_executesql #sql
END
You can't use a variable for your table name. When you do select address from #table SQL expects #table to be a variable of the table type, not a scalar.
You're looking to do something like this:
ALTER PROCEDURE testTblName
(
#id INT,
#name VARCHAR(50)
)
AS
BEGIN
DECLARE #table VARCHAR(50),
#add VARCHAR(150),
#params VARCHAR(200),
#sql VARCHAR(200);
SET #params = '#add VARCHAR(50) OUTPUT';
SET #table = 'DBTest..testMaster'
SET #sql = 'SELECT #add = address FROM ' + #table + ' WHERE id=' + #id + ' AND name=' + #name
EXEC sp_executesql #sql, #params, #add OUTPUT;
...
...
END
I think, u will have to give something like this.
alter PROCEDURE testTblName
(
#id int,
#name varchar(50)
)
AS
BEGIN
declare #table varchar(50)
declare #add varchar(Max)
set #table = 'DBTest..testMaster'
Set #add = 'Select address from ' + #table + ' where id = ' + CAST(#id AS VARCHAR(10)) + ' and name = ' + #name
Exec(#add)
END

Dynamic SQL Procedure

I Have created a procedure which is:
CREATE PROCEDURE test.table_creation ( #ID INT )
AS
BEGIN
DECLARE #SQL VARCHAR(1000)
DECLARE #SchemaName VARCHAR(50)
DECLARE #TableName VARCHAR(100)
SELECT #SQL = 'Create Table ' + #SchemaName + '.' + #TableName + '('
SELECT #SQL = #SQL + 'ID int NOT NULL Primary Key, Name VarChar(10))'
EXEC (#SQL)
END
The problem here is I have to get the table name and Schema name from another table called sample. The query to get those is:
SELECT Source_Schema,Source_Table FROM sample where ID = 12
How do i use these values in the above procedure.
It seems a dubious requirement (you might want to read The Curse and Blessings of Dynamic SQL) but
CREATE PROCEDURE test.table_creation (#ID INT)
AS
BEGIN
DECLARE #SQL NVARCHAR(1000) /*Use nvarchar*/
DECLARE #SchemaName sysname /*Use sysname*/
DECLARE #TableName sysname
SELECT #SchemaName = Source_Schema,
#TableName = Source_Table
FROM sample
where ID = #ID
/*Use QUOTENAME*/
SELECT #SQL = 'Create Table ' + QUOTENAME(#SchemaName) + '.' +
QUOTENAME(#TableName) +
'(ID int NOT NULL Primary Key, Name VarChar(10))'
EXEC (#SQL)
END
SELECT
#SchemaName = Source_Schema,
#TableName = Source_Table
FROM sample where ID = 12

Resources