I wrote a procedure in order to insert the same row into 2 different tables (one table for the sender of the message and an other for the receiver)
CREATE PROCEDURE InsertMsg
#tablesrc VARCHAR(50),
#tabeldest VARCHAR(50),
#src VARCHAR(50),
#dest VARCHAR(50),
#contenu VARCHAR(500)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Sql NVARCHAR(MAX);
SET #Sql = N'INSERT INTO '+ QUOTENAME(#tablesrc)+' (src,dest,contenu,dateEnvoi,Vu) values (#src,#dest,#contenu,GETDATE(),0)'
+ N'INSERT INTO '+ QUOTENAME(#tabeldest)+' (src,dest,contenu,dateEnvoi,Vu) values (#src,#dest,#contenu,GETDATE(),0)'
EXECUTE sp_executesql #Sql
END
Execution
execute InsertMsg 'MSG_RS_80f355a2', 'MSG_RS_80f355a2', 'RS_80f355a2', 'RS_80f355a2', 'test procedure'
I get this error:
Must declare the scalar variable "#src"
You aren't passing the values of your variables #src,#dest and #contenu to sp_executesql. You need to parametrise the statement:
EXECUTE sp_executesql #Sql,
N'#srv varchar(50), #dest varchar(50), #contenu varchar(500)',
#srv = #srv,
#dest = #dest,
#contenu = #contenu;
Related
Here is my issue. I need to create a temp table after executing dynamic SQL and passing params as follows
CREATE PROCEDURE SP1
#param1 varchar(50),
#param2 varchar(50)
AS
BEGIN
DECLARE #PDef varchar(300)
DECLARE #sql varchar(300)
DECLARE #localparam1 varchar(300)
DECLARE #localparam2 varchar(300)
SET #localparam1 = ....
SET #localparam2 = ....
SET #PDef = '#param1 varchar(50), #localparam1 varchar(300)'
SET #sql = 'SELECT * FROM TABL1 WHERE COL1 = #param1, COL2 in (#localparam1)'
EXEC sp_Executesql #sql, #PDef,
#param1 = #param1, #localparam1 = #localparam1
The above works. How do I get the results into a temp table?
I tried
CREATE TABLE #T1 (col1 varchar(50), col2 varchar(50) )
INSERT INTO #T1
EXECUTE #sql -- didn't work
INSERT INTO #T1
EXECUTE (#sql, #PDef, #param1 = #param1, #localparam1 = #localparam1) -- didn't work either
EDIT: Had Looked at the following samples while using EXECUTE
Dynamic SQL results into temp table in SQL Stored procedure and hence used EXECUTE
The accepted answer was:
INSERT into #T1 execute ('execute ' + #SQLString )
omit the 'execute' if the sql string is something other than a procedure
Now see the comments to that accepted answer that question that accepted answer :-)
You've removed sp_executesql from your query for some reason. You can't called sys.sp_executesql if you don't tell SQL Server to:
INSERT INTO #T1
EXECUTE sys.sp_executesql #sql;
INSERT INTO #T1
EXECUTE sys.sp_executesql #sql,
#PDef,
#param1 = #param1,
#localparam1 = #localparam1;
My function is:
Create Function [dbo].[FindMaxRadif](#field nvarchar(15), #tbl nvarchar(15))
returns int
as
begin
declare #query int
set #query = 'select max('+ #field+') from '+ #tbl
return (#query)
end
when Execute this function with this command:
select dbo.FindMaxRadif('IdVehicle','TblVehicle')
I recive this error:
Conversion failed when converting the nvarchar value 'select
max(IdVehicle) from TblVehicle' to data type int.
how to fix it?
Dynamic SQL is not allowed in a User-Defined function. They are not allowed to make data changes, and prohibiting dynamic SQL helps enforce that. You can use a Stored Procedure instead, returning data either as a resultset:
create or alter procedure [dbo].[FindMaxRadif] #field nvarchar(15), #tbl nvarchar(15)
as
/*
create table a(i int)
insert into a(i) values (1),(2);
exec FindMaxRadif 'i','a'
*/
begin
declare #query nvarchar(max);
set #query = concat('select max(', quotename(#field), ') from ', quotename(#tbl));
--print #query
exec(#query);
end
or an output parameter
create or alter procedure [dbo].[FindMaxRadif2] #field nvarchar(15), #tbl nvarchar(15), #rv int output
as
/*
create table a(i int)
insert into a(i) values (1),(2);
declare #v int
exec FindMaxRadif2 'i','a', #v out
select #v
*/
begin
declare #query nvarchar(max);
set #query = concat('select #rv = max(', quotename(#field), ') from ', quotename(#tbl));
--print #query
exec sp_executesql #query, N'#rv int output', #rv = #rv output
end
Am unable to insert record when given all the column names in insert
Below is the SP
ALTER PROCEDURE [dbo].[test]
#tab_name nvarchar(50),
#tab_id int,
#tab_n nvarchar(50),
#tab_q int
as
Begin
declare #sql as nvarchar(50);
declare #counts as int;
select #sql='select #cnt=count(*) from '+#tab_name+' where id='+cast(#tab_id as varchar)+';'
exec sp_executesql #sql,N'#cnt int output', #cnt=#counts output
select #counts as counts
if #counts=1
begin
declare #sql1 as nvarchar(50);
select #sql1='update '+#tab_name+' set quantity='+cast(#tab_q as varchar)+' where id='+cast(#tab_id as varchar)+';'
exec sp_executesql #sql1
end
else
begin
declare #sql2 as nvarchar(50);
set #sql2='insert into '+#tab_name+' (id,name,quantity) values ('+CAST(#tab_id as varchar)+','''+#tab_n+''''
set #sql2+=','+CAST(#tab_q as varchar)+');'
select #sql2
exec sp_executesql #sql2
end
End
"
command: exec dbo.test #tab_name='inventory',#tab_id=4,#tab_n='chiku',#tab_q=123
record gets inserted when column names are removed but does not work with column names during insert.
Please help.
Thanks
It is better to use A nvarchar(max) for dynamic queries with parameters.
Because u never know how long the string can be. unless you know the max lenght of the string.
A dba also told me to use N' as prefix before the string to denote Unicode string literals.
Increase #sql variables size like below:
declare #sql as nvarchar(max);
....
declare #sql1 as nvarchar(max);
...
declare #sql2 as nvarchar(max);
I have written a stored procedure with the following format:
ALTER PROCEDURE usp_data_migration
(#sourceDatabase varchar(50),
#sourceTable varchar(50),
#targetDatabase varchar(50),
#targetTable varchar(50),
#finaloutput varchar(max) output)
AS
BEGIN
----Set of SQL Blocks
END
Then, I am executing the procedure:
DECLARE #finaloutput1 varchar(300)
EXEC usp_data_migration 'Yousuf', 'emp', '[City Branch]', 'emp_tgt', #finaloutput1 output
SELECT #finaloutput1
By executing this way I don't proper output.
When I execute this way:
DECLARE #finaloutput1 varchar(300)
EXEC usp_data_migration #sourceDatabase = 'Yousuf',
#sourceTable = 'emp',
#targetDatabase = '[City Branch]',
#targetTable = 'emp_tgt',
#finaloutput1 output
SELECT #finaloutput1
I get an error message saying:
Msg 119, Level 15, State 1, Line 41
Must pass parameter number 5 and subsequent parameters as '#name = value'. After the form '#name = value' has been used, all subsequent parameters must be passed in the form '#name = value'.
And if I removed my output parameter and execute the procedure, I get my desired output but I am not able to get my result as an output.
EXEC usp_data_migration #sourceDatabase = 'Yousuf',
#sourceTable = 'emp',
#targetDatabase = '[City Branch]',
#targetTable = 'emp_tgt'
What should I do?
Thanks in advance.
The error message is self-explanatory - you should name all of your parameters.
DECLARE #finaloutput1 varchar(300);
EXEC dbo.usp_data_migration -- always use schema prefix
#sourceDatabase = 'Yousuf',
#sourceTable = 'emp',
#targetDatabase = '[City Branch]',
#targetTable = 'emp_tgt',
#finaloutput = #finaloutput1 OUTPUT;
SELECT #finaloutput1;
You have to Select like this
Example 1
create procedure p1
(
#id INT,
#name varchar(20) OUTPUT,
#company varchar(20) OUTPUT
)
AS
BEGIN
Set #name = 'name'
Set #company = 'company'
select #name , #company from table1 where id = #id;
END
GO
Example 2
CREATE PROCEDURE Myproc
#parm varchar(10),
#parm1OUT varchar(30) OUTPUT,
#parm2OUT varchar(30) OUTPUT
AS
SELECT #parm1OUT='parm 1' + #parm
SELECT #parm2OUT='parm 2' + #parm
GO
DECLARE #SQLString NVARCHAR(500)
DECLARE #ParmDefinition NVARCHAR(500)
DECLARE #parmIN VARCHAR(10)
DECLARE #parmRET1 VARCHAR(30)
DECLARE #parmRET2 VARCHAR(30)
SET #parmIN=' returned'
SET #SQLString=N'EXEC Myproc #parm,
#parm1OUT OUTPUT, #parm2OUT OUTPUT'
SET #ParmDefinition=N'#parm varchar(10),
#parm1OUT varchar(30) OUTPUT,
#parm2OUT varchar(30) OUTPUT'
EXECUTE sp_executesql
#SQLString,
#ParmDefinition,
#parm=#parmIN,
#parm1OUT=#parmRET1 OUTPUT,#parm2OUT=#parmRET2 OUTPUT
SELECT #parmRET1 AS "parameter 1", #parmRET2 AS "parameter 2"
go
drop procedure Myproc
Please refer more here
Simple Example:
create procedure proc2 #var int out,#var2 varchar(10) out
as
begin
set #var=(select max(id) from customer);
set #var2=(select name from customer where id=#var);
end
declare #maxid int;
declare #maxname varchar(10);
exec proc2 #maxid out,#maxname out;
select #maxid,#maxname;
DECLARE #dbName nvarchar(128) = 'myDb'
DECLARE #siteId int
exec ('SELECT TOP 1 #siteId = Id FROM ' + #dbName + '..myTbl')
select #siteId
When I run the script above I get the following error
Msg 137, Level 15, State 1, Line 1
Must declare the scalar variable "#siteId".
(1 row(s) affected)
Why and how to fix it?
Thank you
You can use output parameters with sp_executesql.
DECLARE #dbName nvarchar(128) = 'myDb'
DECLARE #siteId int
DECLARE #SQL nvarchar(max) = N'SELECT TOP 1 #outputFromExec = Id FROM ' + quotename(#dbName) + N'..myTbl'
exec sp_executesql #SQL, N'#outputFromExec int out', #siteId out
select #siteId
The dynamic SQL is a different scope to the outer, calling SQL: so #siteid is not recognised
You'll have to use a temp table/table variable outside of the dynamic SQL:
DECLARE #dbName nvarchar(128) = 'myDb'
DECLARE #siteId TABLE (siteid int)
INSERT #siteId
exec ('SELECT TOP 1 Id FROM ' + #dbName + '..myTbl')
select * FROM #siteId
Note: TOP without an ORDER BY is meaningless. There is no natural, implied or intrinsic ordering to a table. Any order is only guaranteed by the outermost ORDER BY
You can try like below
DECLARE #sqlCommand NVARCHAR(4000)
DECLARE #ID INT
DECLARE #Name NVARCHAR(100)
SET #ID = 4
SET #sqlCommand = 'SELECT #Name = [Name]
FROM [AdventureWorks2014].[HumanResources].[Department]
WHERE DepartmentID = #ID'
EXEC sp_executesql #sqlCommand, N'#ID INT, #Name NVARCHAR(100) OUTPUT',
#ID = #ID, #Name = #Name OUTPUT
SELECT #Name ReturnedName
Source : blog.sqlauthority.com
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: Andrew Foster
-- Create date: 28 Mar 2013
-- Description: Allows the dynamic pull of any column value up to 255 chars from regUsers table
-- =============================================
ALTER PROCEDURE dbo.PullTableColumn
(
#columnName varchar(255),
#id int
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
DECLARE #columnVal TABLE (columnVal nvarchar(255));
DECLARE #sql nvarchar(max);
SET #sql = 'SELECT ' + #columnName + ' FROM regUsers WHERE id=' + CAST(#id AS varchar(10));
INSERT #columnVal EXEC sp_executesql #sql;
SELECT * FROM #columnVal;
END
GO
A slight change in the execute query will solve the problem:
DECLARE #dbName nvarchar(128) = 'myDb'
DECLARE #siteId int
exec ('SELECT TOP 1 **''#siteId''** = Id FROM ' + #dbName + '..myTbl')
select #siteId