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);
Related
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
Can we assign string functions Like(Patindex,charindex) along with select command to a dynamic sql variable ?
here is an example that i want assign to a dynamic sql varaible
CREATE PROCEDURE Dynamic_SP
#Table_Name sysname
AS
BEGIN
SET NOCOUNT ON;
DECLARE #DynamicSQL nvarchar(4000)
SET #DynamicSQL = 'SELECT patindex('%,%',ColumnName) FROM '+ #Table_Name
EXECUTE sp_executesql #DynamicSQL
END
GO
EXEC Dynamic_SP 'tblFilm'
i konow it will raise an error at assigning query to the #DynamicSQL ! But is there any way i can do ??
try this:
CREATE PROCEDURE Dynamic_SP
#Table_Name sysname
#ColumnName sysname
AS
BEGIN
SET NOCOUNT ON;
DECLARE #DynamicSQL nvarchar(4000)
SET #DynamicSQL = 'SELECT patindex(''%,%'',' + #ColumnName + ') FROM '+ #Table_Name
-- PRINT (#DynamicSQL) --comment in this and comment out the EXEC(#DynamicSQL) to check whether the query looks good
EXEC (#DynamicSQL)
END
GO
I declared a variable #Obj and assign a complete table name 'ODS..Account' to it.
DECLARE #Obj VARCHAR(255)
Then I used it in a query immediately after FROM Clause. I perceive it is just a string, unable to act as a table object. So how can I fix the code to get it works? Cheers
INSERT Control.dbo.Consistency_Check
(Table_Name
,Schema_Name
,Id
,Incremental_DateTime_Column
)
SELECT
#Tab
,'ODS'
,Id
,SystemModstamp
FROM
#Obj )
You can use a local variable as a scalar value, not as a function. To do this, you need dynamic SQL:
declare #sql varchar(max);
select #sql = '
INSERT Control.dbo.Consistency_Check(Table_Name, Schema_Name, Id, Incremental_DateTime_Column)
SELECT ''#Tab'', 'ODS', Id, SystemModstamp
FROM #Tab
';
select #sql = replace(#sql, '#tab', #tab);
exec sp_executesql #sql;
Slightly different way of doing it with dynamic SQL:
DECLARE #Obj VARCHAR(255) = 'dbo.table'
DECLARE #SQL NVARCHAR(MAX) = ''
SET #SQL = #SQL +
'INSERT Control.dbo.Consistency_Check
(Table_Name
,Schema_Name
,Id
,Incremental_DateTime_Column
)
SELECT
#Tab
,''ODS''
,Id
,SystemModstamp
FROM
' + #Obj + ''
EXEC (#SQL)
You cannot. You probably want to use dynamic query. i.e. workout the SQL query string into a variable and exec using sp_executesql.
You may use the same variable name in the dynamic SQL but I changed it to #p_Tab for the example.
DECLARE #Tab int = 3
DECLARE #SQLString nvarchar(500)
DECLARE #ParmDefinition nvarchar(500) = N'#p_Tab int';
Declare #TableName nvarchar(100) = 'ODS..Account'
/* Build the SQL string dynamicly.*/
SET #SQLString = N'INSERT Control.dbo.Consistency_Check
(Table_Name
,Schema_Name
,Id
,Incremental_DateTime_Column
)
SELECT
#p_Tab
,''ODS''
,Id
,SystemModstamp
FROM
'+ #TableName
EXECUTE sp_executesql #SQLString, #ParmDefinition,
#p_Tab = #Tab
Further reference: https://msdn.microsoft.com/en-us/library/ms188001.aspx
I have a problem with treating table name as variable as I need to put the results to different table each month automatically (without using any advanced procedures to make this query dynamic). Can somebody help me to modify this code and make it work?
declare #exp_dte as date;
set #exp_dte='2015-12-31';
print (#exp_dte);
declare #tab_mth as nvarchar(max);
set #tab_mth=year(#exp_dte)*100+month(#exp_dte);
print (#tab_mth);
declare #tab_name as nvarchar(max)
set #tab_name='mis_anl.dbo.BIK_' + #tab_mth
print (#tab_name);
IF OBJECT_ID (N'#tab_name', N'U') IS NOT NULL
begin
drop table #tab_name
end
select distinct
*
into #tab_name
from table_x
You have to use dynamic SQL to set name at runtime:
DECLARE #exp_dte DATE = '2015-12-31';
DECLARE #tab_name SYSNAME = '[dbo].' + QUOTENAME('BIK_' + FORMAT(#exp_dte, 'yyyyMM'));
IF OBJECT_ID (#tab_name, N'U') IS NOT NULL
BEGIN
EXEC('DROP TABLE' + #tab_name);
END
DECLARE #sql NVARCHAR(MAX) = N'SELECT DISTINCT *
INTO #tab_name
FROM table_x';
SET #sql = REPLACE(#sql, '#tab_name', #tab_name);
EXEC [dbo].[sp_executesql] #sql;
LiveDemo
Remarks:
Try to be more conscise
You could use FORMAT to get yyyyMM (SQL Server 2012+)
Always QUOTENAME generated identifiers to avoid SQL Injection attacks
I strongly recommend to read The Curse and Blessings of Dynamic SQL especially CREATE TABLE #tbl.
use dynamic sql ,you cant user table names as variables
declare #exp_dte as date;
set #exp_dte='2015-12-31';
declare #tab_mth as nvarchar(max);
set #tab_mth=year(#exp_dte)*100+month(#exp_dte);
declare #tab_name as nvarchar(max)
set #tab_name='mis_anl.dbo.BIK_' + #tab_mth
declare #sql1 nvarchar(max)
set #sql1='drop table '+#tab_name;
IF exists(select 1 from information_schema.tables where table_name=#tab_name)
begin
exec(#sql1);
end
declare #sql nvarchar(max)
set #sql='
select distinct
*
into '+#tab_name+'
from table_x'
exec (#sql)
DECLARE #QUERY VARCHAR(200);
SET #QUERY='SELECT COUNT(*) FROM STUD';
I have used this:
EXEC (#QUERY)
EXECUTE sp_executesql #QUERY
but it's not working.
ERROR: Must declare a scalar variable.
how to declare a scalar variable and how to execute this query.
use this
Declare #query nvarchar(max)
Set #query = 'Select count(*) from stud'
EXECUTE sp_executesql #Query
Please try with the following, as you can not execute the string in SSMS directly, You are required to put it in a Temp/Hash table as per your requirement.
DECLARE #QUERY VARCHAR(200);
Declare #tempTabl Table(countval int)
SET #QUERY='SELECT COUNT(*) FROM Blogs';
Insert into #tempTabl
exec (#query)
select * from #tempTabl