update procedure error syntax near '=' - sql-server

I simple want to update the price with for example here 3, but this with a stored procedure.
I already tried it with normal syntax:
update tblPrijs
set PrijsVerkoop = PrijsVerkoop + 1
where PrijsId = '6';
and this works fine.
But my stored procedure always returns :
updatetblPrijssetPrijsVerkoop=PrijsVerkoop+3.00wherePrijsId=11
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '='.
and I don't know what I did wrong..
The stored procedure:
alter PROCEDURE updatePrice
-- Add the parameters for the stored procedure here
#table nvarchar(50),
#field nvarchar(50),
#increase nvarchar(50),
#id nvarchar(50),
#value nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
declare #sql as nvarchar(400);
-- Insert statements for procedure here
set #sql = 'update' + #table + 'set' + #field + '=' + #field + '+' + #increase +
'where' + #id + '=' + #value
print #sql /* drukt het resultaat van concat af */
exec(#sql)
END
GO
This is what I write in my query:
updatePrice'tblPrijs', 'PrijsVerkoop','3.00', 'PrijsId','11'
sorry for the dutch names of fields and tables...
I think it is something small and obvious that is wrong but I just can't see it..
This is in SQL Server 2012
Thank you in advance!

You need to add some spaces in there.
This:
set #sql = 'update' + #table + 'set' +#field + '=' ...
if you add the following parameters:
#table = SomeTable
#field = SomeField
will result in this sql:
updateSomeTablesetSomeField=
Surely that's not what you intended.
I'm assuming by the print #sql statement that you wanted to print your sql statement before executing it. What did it show?
Here's something to try:
set #sql = 'update ' + #table + ' set ' + #field + ' = ' + #field + ' + ' + #increase + ' where ' + #id + ' = ' + #value
I added spaces inside each string, at the start and at the end. Some of those spaces are not strictly needed, but they won't change the outcome either.

Related

Issues encountered with dynamic SQL

ALTER PROCEDURE [dbo].[Create_Subjects]
#Subj_ID nvarchar(9)
AS
DECLARE #First3Digits nvarchar(3);
DECLARE #Result int;
DECLARE #Sql nvarchar(max)
-- Fetching the fiest 3 digits of the subject
SET #First3Digits = SUBSTRING(#Subj_ID,1,3);
-- Check if view is present or not
IF EXISTS (SELECT 1 FROM sys.views WHERE Name = #First3Digits)
BEGIN
SET #Sql = 'select #Result = case when exists (select 1 from dbo.' + quotename(#First3Digits) + ' where SubjectName = ''' + #Subj_ID + ''') then 1 else 0 end';
EXECUTE sp_executesql #Sql, N'#Subj_ID nvarchar(9), #Result bit out', #Subj_ID = #Subj_ID, #Result = #Result out;
-- checking if the subject is present in the view
END
ELSE
BEGIN
-- Create a view as view doesn't exist
SET #Sql = 'create view ' + #First3Digits
+ ' as
(select SubjectName from dbo.Subjects where SubjectName like '+#First3Digits+'%'+');';
EXECUTE sp_executesql #Sql, N'#First3Digits nvarchar(3)', #First3Digits= #First3Digits;
SET #Result = 0;
END
RETURN #Result
GO
This is the code for executing the stored procedure:
EXEC [dbo].[Create_Subjects] '1234567890'
Error encountered:
Msg 156, Level 15, State 1, Line 28
Incorrect syntax near the keyword 'view'
Msg 102, Level 15, State 1, Line 29
Incorrect syntax near ')'
There are a number of issues with your SQL. But firstly the way to debug them is to print the SQL without executing it, then its normal SQL and you can easily identify what is wrong with it.
No brackets are allowed around the SQL making up the view.
You have to quote your strings as per normal, which means doubling up the quotes in the dynamic string.
Use quotename again as suggested in the comments.
There is no need to pass the parameter #First3Digits into sp_executesql because by that point you've used its value - which you have to do given you are creating a view.
set #Sql = 'create view dbo.' + quotename(#First3Digits)
+ ' as'
+ ' select SubjectName'
+ ' from dbo.Subjects'
+ ' where SubjectName like ''' + #First3Digits + ''' + ''%'';';
-- This is how you debug dynamic SQL
print(#Sql);
execute sp_executesql #Sql;
Note: As I mentioned in your previous question, with the information provided, this seems to be a really bad design. There is almost certainly a better way to solve your bigger picture problem. As commented by Martin Smith an Inline Table Valued Function might be worth investigating.

Error while using variable declaration Incorrect syntax near '+#TABLENAME1+'

DECLARE #SQLSTRING VARCHAR(1500);
DECLARE #TABLENAME1 VARCHAR(30)='NOV19_COMBINE'
---------------TABLE CREATION WITH FILE NAME--------------------------
SET #SQLSTRING = 'SELECT
CONVERT(VARCHAR('+ cast((select max(len(EMAIL)) from '+#TABLENAME1+' ) as VARCHAR(50))+'), EMAIL ) AS EMAIL,
IDENTITY (INT,1,1) AS RECORDID
INTO FOI_'+#TABLENAME1+'_CONV
FROM '+#TABLENAME1+' A'
PRINT #SQLSTRING
Error:
Msg 102, Level 15, State 1, Line 8
Incorrect syntax near '+#TABLENAME1+'.
You have an issue here:
CONVERT(VARCHAR('+ cast((select max(len(EMAIL)) from ' + #TABLENAME1 + ' ) as VARCHAR(50))+')
where you are trying to select from a table defined in #TABLENAME1. That also needs to be part of your dynamic SQL.
However you have another issue with your convert(varchar( code in that you cannot use a variable as as the length to varchar(). I suggest using varchar(max) because that only uses the storage required.
I have also made your dynamic SQL safe from injection with the use of QUOTENAME which I recommend you use in future.
Fixed version:
DECLARE #SQLSTRING VARCHAR(1500);
DECLARE #TABLENAME1 VARCHAR(30) = 'NOV19_COMBINE'
---------------TABLE CREATION WITH FILE NAME--------------------------
SET #SQLSTRING = 'SELECT CONVERT(VARCHAR(max), EMAIL) AS EMAIL, IDENTITY (INT,1,1) AS RECORDID INTO '
+ QUOTENAME('FOI_' + #TABLENAME1 + '_CONV') + ' FROM '
+ QUOTENAME(#TABLENAME1) + ' A'
PRINT #SQLSTRING
There is no reason I can think of to do it this way, but as an academic exercise, if one really needed the exact length of the EMAIL column then one would use the following query:
declare #SQLSTRING nvarchar(max), #TABLENAME1 VARCHAR(30) = 'NOV19_COMBINE', #EMAILLENGTH int
SET #SQLSTRING = 'SELECT #Length = max(len(EMAIL)) from ' + QUOTENAME(#TABLENAME1)
EXECUTE sp_executesql #SQLSTRING, N'#Length int OUTPUT', #Length = #EMAILLENGTH OUTPUT
SET #SQLSTRING = 'SELECT CONVERT(VARCHAR(' + convert(varchar(4),#EMAILLENGTH) + '), EMAIL) AS EMAIL'
+ ', IDENTITY (INT,1,1) AS RECORDID'
+ ' INTO ' + QUOTENAME('FOI_' + #TABLENAME1 + '_CONV')
+ ' FROM ' + QUOTENAME(#TABLENAME1) + ' A'
PRINT #SQLSTRING
This requires 2 sections of dynamic SQL, the first to find the length of the EMAIL column, which is then used to built the dynamic SQL for the actual query.

Invalid Column name on parameter input

Really wrecking my head here and as with many sql mess up I know it is probably something silly and stupid but I just cant seem to get it to work.
I have a stored procedure which is this..
ALTER PROCEDURE [dbo].[RETURN_DATA](#TABLE_param VARCHAR(7),#COUNTRY_param VARCHAR(2),#FILEDATE_param int,#TTKT_param VARCHAR(6))
AS
BEGIN
SET NOCOUNT ON;
SELECT #SQL = 'Select * from ' + #TABLE_param + ' WHERE COUNTRY = ' + #COUNTRY_param + ' AND MONTH(Fil_Dte) = ' + cast(#FILEDATE_param as varchar(20)) + ' AND TRNN = '+ #TKTT_param
EXECUTE(#SQL)
END
I'm using it in a vb.net windows form app so applying the parameters there. But trying to run it in SSMS with this
exec RETURN_DATA #COUNTRY_param='GB',#FILEDATE_param=4,#TABLE_param='table30',#TTKT_param='000000'
Returns the error
Invalid column name 'GB'. which i find strange as I never called for a column called GB but called for rows with GB in the column COUNTRY in my where clause?
I know this hopefully is a simple fix so any help would be greatly appreciated and also even if you think theres a better way to go about writing the SP!
Thanks in advance guys.
I'd recommend parameterising the SQL which will guard against SQL injection and you don't have to worry about escaping quotes as below
ALTER PROCEDURE [dbo].[RETURN_DATA](#TABLE_param VARCHAR(7),#COUNTRY_param VARCHAR(2),#FILEDATE_param int,#TTKT_param VARCHAR(6))
AS
BEGIN
SET NOCOUNT ON;
SELECT #SQL = 'Select * from ' + #TABLE_param + ' WHERE COUNTRY = ''' + #COUNTRY_param + ''' AND MONTH(Fil_Dte) = ' + cast(#FILEDATE_param as varchar(20)) + ' AND TRNN = '''+ #TKTT_param +''''
EXECUTE(#SQL)
END
Use sp_executesql to run dynamic sql
DECLARE #SQL NVARCHAR (4000);
SET #SQL = '
Select *
from ' + QUOTENAME(#TABLE_param) + '
WHERE COUNTRY = #COUNTRY_param
AND MONTH(Fil_Dte) = #FILEDATE_param
AND TRNN = #TTKT_param
';
EXEC sp_executesql #SQL,
N'#COUNTRY_param VARCHAR(2), #FILEDATE_param int, #TTKT_param VARCHAR(6)',
#COUNTRY_param, #FILEDATE_param, #TTKT_param;
sp_executesql

Dynamic SQL update Image

I have been battling with this statement:
ALTER PROCEDURE [dbo].[transact_image_update]
-- Add the parameters for the stored procedure here
#transact_recordID_int int,
#image1_bin image,
#image2_bin image,
#transact_referenceNo_str nvarchar(25),
#userID_last uniqueidentifier,
#tableName nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
DECLARE #sqlUpdt01 nvarchar(4000)
SET #sqlUpdt01 = '
Update [dbo].[' + #tableName + '] SET [image1_bin] = '+ CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), #image1_bin), 2)
+ ', [image2_bin] = '+ CONVERT(VARCHAR(MAX), CONVERT(VARBINARY(MAX), #image2_bin), 2)
+', [userID_last] = '''+ convert(nvarchar(4000),#userID_last)
+ ''' WHERE (transact_recordID_int = '+convert(varchar,#transact_recordID_int) +')
AND ([transact_referenceNo_str] = ''' +convert(varchar, #transact_referenceNo_str)
+''' )
AND (locked_bol = 0)
'
exec sp_executesql #sqlUpdt01
Basically, I have many DB tables with similar schema but different names (for types of transactions) and would like this ONE procedure to make the update given the table name as argument. This script compiles successfully but execution cannot update the image field. Is there a conversion I'm missing?
Please help.
in correct type cast in below line
in correct line
+ ''' WHERE (transact_recordID_int = '+ convert(varchar,#transact_recordID_int) +
correct line
+ ''' WHERE (transact_recordID_int = '+ #transact_recordID_int +

SQL Server: executing dynamic/inline sql table name within EXEC and passing geometry as geometry parameter

I'm trying to execute an inline SQL statement within a stored procedure. I'm working with SQL Server 2008.
The problem is that I can't execute the first inline statement (with WHERE clause). It crashes because the string within EXEC(...) is dynamically created and all concatenated variables must be of type varchar.
Error that appears when calling procedure:
An expression of non-boolean type specified in a context where a
condition is expected, near 'ORDER'.
The procedure looks like:
CREATE PROCEDURE loadMyRows
#table_name nvarchar(50),
#bounding_box varchar(8000)
AS
BEGIN
-- *********************************** COMMENT *********************************
-- ** This two code lines are correct and will return true (1) or false (0), **
-- ** but they doesn't work within inline EXEC(...) **
--DECLARE #bb geometry = geometry::STGeomFromText(#bounding_box, 4326);
--select TOP(5) wkt.STWithin(#bb) AS 'bool'
-- *********************************** COMMENT *********************************
IF #bounding_box <> ''
BEGIN
DECLARE #bb geometry = geometry::STGeomFromText(#bounding_box, 4326);
EXEC(
'SELECT TOP (' + #row_limit + ') * ' +
'FROM ' + #real_table_name + ' ' +
'WHERE wkt.STWithin('+#bb+') ' + -- <-- doesn't work :-(
-- 'WHERE wkt.STWithin(geometry::STGeomFromText('''+#bounding_box+''', 4326)) ' +
-- ^^ doesn't work, too :-(
'ORDER BY id ASC '
);
END
ELSE
BEGIN
EXEC(
'SELECT TOP (' + #row_limit + ') * ' +
'FROM ' + #real_table_name + ' ' +
'ORDER BY id ASC'
);
END
END
I've found a working solution for this problem. The way the MSDN showed me was http://msdn.microsoft.com/en-US/library/ms175170.aspx. There's written:
[...] the string is executed as its own self-contained batch.
That let me know, if I want to execute a dynamic statement with a table variable as string, it's the same as I would execute the query without the EXECUTE command, like:
SELECT TOP(#row_limit) *
FROM #real_table_name
WHERE ...
ORDER BY id ASC;
And this would probably not work for the table name.
So, if I write instead:
DECLARE #sql_statement nvarchar(MAX) = 'SELECT TOP(#limit) *
FROM ' + #real_table_name + '
ORDER BY id ASC';
-- declaration of parameters for above sql
DECLARE #sql_param_def nvarchar(MAX) = '#limit int';
EXECUTE sp_executesql #sql_statement, #sql_param_def, #limit = #row_limit;
Then, this would work. This is because I define the #sql_statement simply as a concatenated string which will just resolve the dynamic table name at runtime to a string with the name of the real existing table. The #limit parameter is untouched and is still a parameter.
If we then execute the batch we only must pass a value for the #limit parameter and it works!
For the geometry parameter it works in the same way:
DECLARE #bb geometry = geometry::STGeomFromText(#bounding_box, 4326);
SET #sql_statement = 'SELECT TOP(#limit) *
FROM ' + #real_table_name + '
WHERE wkt.STWithin(#geobb) = 1
ORDER BY id ASC';
-- NOTE: This ' = 1' must be set to avoid my above described error (STWithin doesn't return a BOOLEAN!!)
-- declaration of parameters for above sql
SET #sql_param_def = '#limit int, #geobb geometry';
EXECUTE sp_executesql #sql_statement, #sql_param_def, #limit = #row_limit, #geobb = #bb;
Hope this was clear ;-)
create proc usp_insert_Proc_Into_temp
#tempTable nvarchar(10) output
as
begin
set #tempTable = '##temp'
declare #query nvarchar(200)
--Select statement
set #query = 'select 1 as A,2 as B, 3 as C into'+ ' '+#tempTable+''
exec(#query)
end
go
declare #tempTable nvarchar(10)
exec usp_insert_Proc_Into_temp #tempTable output
exec('select * from' + ' '+ #tempTable+'')
exec ('drop table'+ ' '+#tempTable+'')

Resources