Simple question but wasting time to looking for the answer. I have stored procedure like this
ALTER PROCEDURE [dbo].[sinau]
#id varchar (max)
AS
BEGIN
SET NOCOUNT ON;
declare
#select varchar (4000),
#from varchar (4000),
#where varchar (4000),
#final varchar (4000)
-- Insert statements for procedure here
set #select = 'select *'
set #from = 'from permohonan'
set #where= 'where idpermohonan= '+#id
set #final=#select+#from+#where
execute (#final)
END
After I input parameter and exec that SP, the result is
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '='.
Could you fix this ? Thanks
You need to add spaces:
set #select = 'select * '
set #from = 'from permohonan '
set #where= 'where idpermohonan= '+#id
because without it you get:
select *from permohonanwhere idpermohonan= ...
You should always check your query:
IF #debug = 1
PRINT #select+#from+#where;
But for completness you should not concatenate string and use parametrized sp_executesql:
ALTER PROCEDURE [dbo].[sinau]
#id varchar(MAX)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #query NVARCHAR(MAX);
SET #query =
N'SELECT *
FROM permohonan
WHERE idpermohonan = #id;';
EXEC [dbo].[sp_executesql]
#query,
N'#id VARCHAR(MAX)',
#id;
END
Using Dynamic SQL can be tricky so I strongly recommend to read The Curse and Blessings of Dynamic SQL
Related
Hello I am having a problem here.
I wanted to read subjectname from a dynamic table name and the save it to a variable.
but i am getting an error
DECLARE #retval varchar(200)
DECLARE #sSQL nvarchar(500);
DECLARE #ParmDefinition nvarchar(500);
DECLARE #academicYear varchar(200) = '20212022';
Declare #subjectId varchar(200) = '202041962';
DECLARE #tablename nvarchar(50) = 'abc' + CAST(#academicyear As varchar)
DECLARE #CONDITION NVARCHAR(128)
SET #CONDITION = 'WHERE [subjectid] = 202041962'
SELECT #sSQL = N'SELECT #retvalOUT = [subjectname] FROM ' + #tablename + #CONDITION;
SET #ParmDefinition = N'#retvalOUT varchar OUTPUT';
EXEC sp_executesql #sSQL, #ParmDefinition, #retvalOUT=#retval OUTPUT;
SELECT #retval;
If you actually looked at the value of #sSQL eg by printing it, you'll note it contains FROM abc20212022WHERE, therefore,
you are not delimiting your table names - use quotename()
you need a space between your table name and the where
you should always specify a length for a varchar value (you don't need to cast a variable when concatenating two strings but you should be consistent with your use of [n]varchar)
using concat to concatenate strings is easier and safer
When I execute a stored procedure using openrowset, which has dynamic SQL in it, it throws an error
Contains dynamic SQL. Consider using WITH RESULT SETS
An example is as follows.
select output.*
from openrowset ('SQLOLEDB','SERVER=(local);Trusted_Connection=yes;',
'SET FMTONLY OFF;SET NOCOUNT ON; exec storedproc ') as output
Since I have many output parameters, is there a simple way to display all the columns?
Note: I have to use openrowset as the stored procedure is being executed inside a script (R).
I also tried the following but didn't work.
declare #sqlstmt nvarchar(max)
declare #queryout nvarchar(max)
set #queryout = 'storedproc #parameter1=''''D'''', #param2=''''08/19/2018'''', '
set #queryout = '''exec ' + #queryout
set #sqlstmt = N'select outputprod.* from openrowset (''SQLOLEDB'',''SERVER=(local);Trusted_Connection=yes;'' , ' + #queryout + ''') as outputprod'
print(#sqlstmt)
exec (#sqlstmt)
You can use Dynamic Query with full select statement inside varchar variable then execute it with EXEC. see here.
for example
DECLARE #sqlCommand varchar(1000)
DECLARE #columnList varchar(75)
DECLARE #city varchar(75)
SET #columnList = 'CustomerID, ContactName, City'
SET #city = '''London'''
SET #sqlCommand = 'SELECT ' + #columnList + ' FROM customers WHERE City = ' + #city
EXEC (#sqlCommand)
Modify the Stored procedure with output parameter to return the generated query, to avoid dynamic stored procedure being passed.
DECLARE #queryout NVARCHAR(max)
DECLARE #sqlstmt NVARCHAR(max)
EXEC storedproc #queryout OUTPUT
SET #sqlstmt = N'SET FMTONLY OFF;SET NOCOUNT ON;' + #queryout
select output.* from openrowset (
'SQLOLEDB','SERVER=(local);Trusted_Connection=yes;', #sqlstmt) as output
I am trying to store next value for the sequence into a variable and the statement is called in a dynamic sql as below.
DECLARE #Sequence VARCHAR(100) = 'IMEIIDLookUP'
DECLARE #NextVal INT
DECLARE #SQL NVARCHAR(4000)
SELECT #SQL = 'SELECT (NEXT VALUE FOR [dbo].' + QUOTENAME(#Sequence) + ')'
SELECT #NextVal = EXEC (#SQL)
SELECT #NextVal
The above query fails with error
Incorrect syntax near the keyword 'EXEC'.
What would be the correct syntax here? Having said that, I cannot avoid using dynamic sql.
Use sp_executesql:
DECLARE #Sequence VARCHAR(100) = 'IMEIIDLookUP';
DECLARE #NextVal INT;
DECLARE #SQL NVARCHAR(4000);
SELECT #SQL = 'SELECT #NextVal = (NEXT VALUE FOR [dbo].' + QUOTENAME(#Sequence) + ')';
exec sp_executesql #SQL, N'#NextVal int output', #NextVal = #NextVal output;
SELECT #NextVal;
I have a block code to create a procedure:
CREATE PROCEDURE GetTableinfomation
#table nvarchar(50),
#column nvarchar(50),
#valuedk nvarchar(50)
AS
BEGIN
SELECT *
FROM #table
WHERE #column = #valuedk
END
and I have an error.
Msg 1087, Level 15, State 2, Procedure GetTableinfomation, Line 7
Must declare the table variable "#tenbang".
Why?
You cannot use SQL parameters for table names and columns, only for variables.
You could get around this by using dynamic SQL:
DECLARE #SQL nvarchar(4000)
DECLARE #PARAMS nvarchar(4000)
SET #SQL = 'SELECT * FROM '
+ QUOTENAME(#table,'"') + ' WHERE '
+ QUOTENAME(#column,'"') + '= #param1'
SET #PARAMS = '#param1 nvarchar(50)'
EXEC sp_executesql #SQL, #PARAMS, #param1=#valuedk
See the documentation on sp_executesql for more information:
http://msdn.microsoft.com/en-us/library/ms188001.aspx
I am trying to write a simple stored proc which takes three arguments 'database name one', 'database name two' and 'table name'. The sql will then perform a row count for the defined table in each database and store it.
Working on it piecemeal I have hit the first problem in that you can't do
select * from #tablename
I know you can use dynamic sql with the exec command but this is not ideal as I can't return values.
The following example looks like it should work but doesn't.
declare #tablename as nvarchar(500)
declare #sqlstring as nvarchar(500)
declare #parmdefinition as nvarchar(500)
declare #numrows as bigint
set #tablename = N'dummy_customer'
set #parmdefinition = N'#tablenameIN nvarchar(500), #numrowsOUT as bigint OUTPUT'
select #sqlstring = 'select #numrowsOUT = count(*) from #tablenameIN'
select #sqlstring
exec sp_executesql #sqlstring, #parmdefinition, #tablenameIN = #tablename, #numrowsOUT = #numrows OUTPUT
select #numrows
The error message given is
Msg 1087, Level 16, State 1, Line 1
Must declare the table variable "#tablenameIN".
Currently using SQL Server 2008 SP2.
Edit:
We're doing this because we are doing a migration and the customer wants a report which shows the row count for each table in the source and destination database. As there are many tables being able to use sp_MSForEachTable to call the stored proc seems ideal.
Edit:
The final solution for future reference is
declare #tablename as nvarchar(500)
declare #sqlstring as nvarchar(500)
declare #parmdefinition as nvarchar(500)
declare #numrows as bigint
set #tablename = N'dummy_customers'
set #parmdefinition = N'#tablename nvarchar(500), #numrowsOUT as bigint OUTPUT'
select #sqlstring = 'select #numrowsOUT = count(*) from ' + quotename(#tablename)
exec sp_executesql #sqlstring, #parmdefinition, #tablename = #tablename, #numrowsOUT = #numrows OUTPUT
select #numrows
You'd have to use dynamic sql, and concatenate the table name into the SQL string to then execute via sp_executsql:
select #sqlstring = 'select #numrowsOUT = count(*) from ' + QUOTENAME(#tablename)
EXECUTE sp_executesql ....