Incorrect syntax near 'month' with dynamic number - sql

While running this query
update p_leave_allocation_14122015
set 'month' + #actualMonth = #actualleavedays
where year = #actualYear
and emp_card_no = #emp_card_no
I get an error:
Incorrect syntax near 'month'.
The table p_leave_allocation_14122015 has columns like month1, month2, month3,.....
In my update query what I want is month will be hardcoded and the no of month will be dynamic based on some conditions which I have written.
But when I tried with the above query I got the mentioned error.
I am using SQL Server 2005.
Kindly suggest

You should try something like below,
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'update p_leave_allocation_14122015
SET MONTH'+CAST(#actualMonth AS VARCHAR(2)) +' = ' + CAST(#actualleavedays AS VARCHAR(10))+
' WHERE YEAR = '+ CAST(#actualYear AS VARCHAR(4))+
' AND emp_card_no = '+CAST(#emp_card_no AS VARCHAR(100)) +'';
PRINT #sql --Note: Check the query first before updating.
EXEC SP_EXECUTESQL #sql;

declare #sql varchar(max)=''
declare #actualMonth int=10
declare #actualleavedays int=20
declare #actualYear int=2015
declare #emp_card_no varchar(8)='Emp1010'
set #sql = 'update p_leave_allocation_14122015
set month' + cast(#actualMonth as varchar(2)) + '='+ cast(#actualleavedays as varchar(3))+
' where year ='+ cast(#actualYear as varchar(4)) + 'and emp_card_no ='+ #emp_card_no
print #sql --check generated sql query
exec(#sql)

You need to use dynamic query to do this
DECLARE #sql NVARCHAR(max) = ''
SET #sql = 'update p_leave_allocation_14122015 set month'
+ Cast(#actualMonth AS VARCHAR(10)) + ' = '
+ Cast(#actualleavedays AS VARCHAR(10))
+ ' where year = #actualYear and emp_card_no = #emp_card_no '
EXEC Sp_executesql
#sql,
N'#actualYear int,#emp_card_no int',
#actualYear,
#emp_card_no
Note: If #actualMonth or #actualleavedays is of integer type then you need to cast it to varchar to work in dynamic query

try this
make a string and stored in nvarchar variable and then execute query like below
DECLARE #SqlQuery NVARCHAR(MAX)
SET #SqlQuery ='update p_leave_allocation_14122015 set month' + #actualMonth + '=' + #actualleavedays + ' where year = '+ #actualYear + ' and emp_card_no ='+ #emp_card_no
EXEC(#SqlQuery)

Related

Dynamic Sp_Executesql failing on datetime conversion error

I have a very simple dynamic SQL query that specifically needs to be called using sp_executesql with parameters. This query works fine in regular dynamic SQL, but fails when using sp_executesql on a conversion error.
I have tried many combinations of dynamic SQL, but none of them seem to work specifically for datetime conversions related to sp_executesql.
declare
#sql_nvarchar nvarchar(max),
#datetime datetime = GETDATE(),
#sqlparams nvarchar(max),
#tablename nvarchar(max) = 'SomeTableName'
Set #sql_nvarchar =
N'
Select *
from ' + #tablename + '
where Date > ''' + convert(nvarchar(23), #datetime, 101) + ''' '
Set #sqlparams =
N'
#datetime datetime,
#tablename nvarchar(max)
'
EXEC(#sql_nvarchar)
EXEC [sp_executesql] #sql_nvarchar,#sqlparams, #datetime, #tablename
The first exec correctly returns the desired query, the second EXEC throws an error: 'Error converting data type nvarchar(max) to datetime.'
You cannot parameterize an identifier, such as a table name. So, phrase this as:
Set #sql_nvarchar = N'
Select *
from ' + #tablename + '
where Date > #datetime
';
Set #sqlparams = N'#datetime datetime'
exec sp_executesql #sql_nvarchar, #sqlparams,
#datetime=#datetime

Could not able to figure out the error near convert sql

It is giving me an error saying 'Incorrect syntax near the keyword 'convert'.' Could not able to figure out what could be done to remove it.
ALTER PROCEDURE [dbo].[sp_convert_unix_timestamp]
#table_name nvarchar(250), ---Staging Table
#DateTimeString nvarchar(max)
AS
BEGIN
if isnull(#DateTimeString,'') <> '' begin
declare #SQLString Nvarchar(max)
declare #UpdateString Nvarchar(max)
declare #initialepoch Nvarchar(10)
set #initialepoch = '19700101'
SELECT #SQLString = coalesce(#SQLString + ',', '') +
'convert(varchar, dateadd(ss, convert(Int, ' + value + '),' + #initialepoch + '), 120)'
FROM STRING_SPLIT(#DateTimeString, ',')
WHERE RTRIM(value) <> ''
select #UpdateString = 'Update [' + #table_name + '] set ' + #SQLString
exec (#SQLString)
end
END
Firstly, let's fix the SP so it's no open to Injection, and the datatype choice for #table_name:
ALTER PROCEDURE [dbo].[sp_convert_unix_timestamp]
#table_name sysname, ---Staging Table
#DateTimeString nvarchar(max)
AS
IF ISNULL(#DateTimeString, '') <> ''
BEGIN
DECLARE #SQLString nvarchar(MAX);
DECLARE #UpdateString nvarchar(MAX);
DECLARE #initialepoch nvarchar(10);
SET #initialepoch = N'19700101';
SELECT #SQLString = COALESCE(#SQLString + ',', '') + N'convert(varchar(10), dateadd(ss, convert(Int, ' + QUOTENAME(value,N'''') + N'), + #dinitialepoch), 120)'
FROM STRING_SPLIT(#DateTimeString, ',')
WHERE RTRIM(value) <> '';
SELECT #UpdateString = N'Update ' + QUOTENAME(#table_name) + N' set ' + #SQLString;
PRINT #UpdateString;
EXEC sp_executesql #SQLString, N'#dinitialepoch nvarchar(10)', #dinitialepoch = #initialepoch;
END;
If we were to run that SP, EXEC [dbo].[sp_convert_unix_timestamp] N'MyTable', N'20170720,20170721';, you'd get this output (and magcially, you know the reason why it's not working):
Update [MyTable] set convert(varchar, dateadd(ss, convert(Int, '20170720'), + #dinitialepoch), 120),convert(varchar, dateadd(ss, convert(Int, '20170721'), + #dinitialepoch), 120)
There is no column in your SET clause. You simply have UPDATE [Table] SET [Value]; The format of an UPDATE statement is UPDATE [Table] SET [Column] = [Value];. What column(s) that needs to be updated, however, I have no idea...

Comma seperated values to SQL IN STATEMENT

If i have a comma separated list of values:
A1,B2,B3
How do i pass this into a variable and then form it into an SQL IN statement.
DECLARE #DATE AS VARCHAR(50)
SELECT #DATE = CONVERT(VARCHAR(8), Getdate(), 112)
--PRINT #DATE
DECLARE #TIME AS VARCHAR(50)
--PRINT TIME
SELECT #TIME = Replace(CONVERT(VARCHAR(5), Getdate(), 108), ':', '')
DECLARE #ID AS VARCHAR(50)
SELECT #ID = Replace(W0128001, 32322, 32323, 3232323, 2323232, ',', ',')
--PRINT #ID
DECLARE #QUERY NVARCHAR(MAX);
SET #QUERY = 'SELECT * INTO BACKUPTABLE_' + #DATE + #TIME
+ '
FROM TABLE
WHERE ID IN (' + '''' + #ID + ''')'
--EXEC #query
PRINT #QUERY
I have tried to do a replace above but i want it so that an end user can PASTE into the values and my script will take care of the commas and properly form it. It should also strip out the last commas from the end.
My output needs to read:
SELECT * INTO BACKUPTABLE_201606061503
FROM TABLE
WHERE ID IN ('W0128001','32322','32323','3232323','2323232')
For one thing, you don't surround it with single quotes:
SET #QUERY = 'SELECT * INTO BACKUPTABLE_' + #DATE + #TIME + '
FROM TABLE
WHERE ID IN (' + #ID + ')';
There are other ways to pass comma-delimited values to a SQL statement, including using a split() function or XML.
CREATE PROCEDURE [dbo].[CreateBackupTable]
#ID varchar(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #DATE VARCHAR(50)= CONVERT(VARCHAR(8), Getdate(), 112);
DECLARE #TIME VARCHAR(50) = Replace(CONVERT(VARCHAR(5), Getdate(), 108), ':', '')
declare #xml xml,#SQL NVARCHAR(MAX);
set #xml = N'<root><r>' + replace(#ID,',','</r><r>') + '</r></root>'
SET #SQL = N' SELECT * INTO ' + QUOTENAME('BACKUPTABLE_' + #DATE + #TIME)
+ N' from TableName '
+ N' where ID IN (
select r.value(''.'',''varchar(max)'') as item
from #xml.nodes(''//root/r'') as records(r)
)'
exec sp_executesql #sql
, N'#ID varchar(100), #xml XML'
, #ID
, #Xml
END

Make multiple columns into one column in sql

I have a table Employee which have several fields like FirstName,LastName,Email,....... . So what i want to do is that in my case selection of column is dynamic
Declare #columnNeeded nvarchar(max)
Example one
Set #columnNeeded = 'FirstName,Email'
Select #columnNeeded from Employee
Example Two
Set #columnNeeded = 'FirstName,LastName'
Select #columnNeeded from Employee
This is pretty simple , now what i want is that regardless of what column will be in result set i need all column selected in one column as comma seperated string . I saw Group_Concat() in mysql but don't know how to do this in sql .So is this possible ?
You can do this with dynamic SQL:
declare #sql nvarchar(max) = 'select #columns from Employee';
declare #columnNeeded nvarchar(max) = 'FirstName,Email';
set #sql = replace(#sql, '#columns', #columnNeeded);
exec sp_executesql #sql;
EDIT:
If you want them as one column, you could do:
declare #sql nvarchar(max) = 'select #columns from Employee';
declare #columnNeeded nvarchar(max) = 'FirstName,Email';
set #sql = replace(replace(#sql, '#columns', #columnNeeded), ',', '+'',''+');
exec sp_executesql #sql;
To type-safe you would cast the column values:
declare #tmp nvarchar(4000) = 'cast(' +
replace(#columnNeeded, ',', ', nvarchar(4000)), cast(') +
', nvarchar(4000))'
set #sql = replace(replace(#sql, '#columns', #columnNeeded), ',', '+'',''+');
If this works as expected, it adds cast(<col> as nvarchar(4000)) to each of the columns in the list.
You have to use Dynamic SQL. Since you have different Data types in your table you may have to convert the columns to Varchar to concatenate the result into single column.
DECLARE #sql NVARCHAR(max),
#cols NVARCHAR(max) ='FirstName,Email'
SELECT #cols = 'convert(varchar(100),'
+ Replace(#cols+')+', ',', ')+'',''+convert(varchar(100),')
SELECT #cols = LEFT(#cols, Len(#cols) - 1)
SET #sql ='select ' + #cols + ' from Employee '
--print #sql
EXEC Sp_executesql #sql;
Working Example :
CREATE TABLE #test1([Key] INT,ID INT,Value VARCHAR(2))
INSERT #test1
VALUES (1,1,'C' ),(2,1,'C' ),(3,1,'I' )
DECLARE #sql NVARCHAR(max),
#cols NVARCHAR(max) ='ID,Value'
SELECT #cols = 'convert(varchar(100),'
+ Replace(#cols+')+', ',', ')+'',''+convert(varchar(100),')
SELECT #cols = LEFT(#cols, Len(#cols) - 1)
SET #sql ='select ' + #cols + ' from #test1 '
EXEC Sp_executesql #sql;

How do I query a value dynamically in T-SQL?

For whatever reason, I can't seem to get a value out dynamically from SQL.
declare #SQL nvarchar(max)
declare #FieldName nvarchar(255)
declare #FieldValue nvarchar(max)
select #SQL = 'SELECT TOP 1 ' + #fieldname
+' FROM MyTable WHERE CM_CASE_YEAR = ' + LEFT(#ClaimNumber, 2)
+' AND CM_CASE_NUMBER = ' + RIGHT(#ClaimNumber, 6)
exec sp_executesql #sql, #FieldValue OUTPUT
select #FieldName + ' - ' + #FieldValue
When I run the #SQL query in another window, it displays one column with one value.
But, unfortunately when I try this, #FieldValue always comes back NULL.
Did I miss something the day they taught sp_executesql? Obviously! But what?
See this example
DECLARE #SQL NVARCHAR(MAX)
DECLARE #FieldName sysname = 'name'
DECLARE #FieldValue NVARCHAR(MAX)
SELECT #SQL = 'SELECT TOP 1
#FieldValue =' + QUOTENAME(#FieldName) + ' FROM sys.objects'
EXEC sp_executesql #SQL,
N'#FieldValue nvarchar(max) OUTPUT',
#FieldValue =#FieldValue OUTPUT
SELECT #FieldName + ' - ' + #FieldValue
sp_executesql returns (generates) a resultset. #FieldValue is meaningless in the code above - sp_executesql won't put any value into that variable.