Syntax error in sql exec count - sql

declare #message int,#DBName varchar(50)
set #DBName ='AutoChip'
exec('select '+#message+'= count(*) from '+#DBname+'.[dbo].[Report List]')
print #message
Getting an error trying to print the count
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '='.
I will pass DBname dynamically, I am using a cursor

The variable name needs to be part of dynamic SQL you are creating, but it's shouldn't be concated with it.
For example, if your variable is of type varchar and has value as 'ERROR', resultant query will be
select ERROR= count(*) from YOURDBNAME.[dbo].[Report List]
so the correct one is below.
exec('select #message= count(*) from '+#DBname+'.[dbo].[Report List]')
You need to include variable declaration and initialization in dynamic sql. You cannot set a value of external variable inside a dynamic sql as the context of execution will be different.

Related

How can I insert text, from a subquery, in a function request

I'm using a function on the Master database (xp_fileexist) to check if a folder is empty or not. If it's empty I want a 0, otherwise a 1.
If I hardcode the folder name ('C:\Import\2016-01-01\Transaction') it works fine. What doesn't work for me, is having the date as a variable, as the date changes from time to time. For the variable, I use this:
'C:\Import\The Netherlands\'+CAST((select workingdate from system..tmpworkingdate) AS VARCHAR(10))+'\Transaction(BP)'
This is the code I've tried:
CREATE TABLE #temp (FileExists int, IsDirectory int, ParentDirExists int)
INSERT INTO #temp
EXEC master..xp_fileexist ('C:\Import\'+CAST((select workingdate from system..tmpworkingdate) AS VARCHAR(10))+'\Transaction(BP)')
IF EXISTS(SELECT IsDirectory FROM #temp WHERE IsDirectory=1)
PRINT 1
ELSE
PRINT 0
DROP TABLE #temp
Error: Msg 102, Level 15, State 1, Line 5 Incorrect syntax near
'C:\Import\The Netherlands\'. Msg 156, Level 15, State 1, Line 5
Incorrect syntax near the keyword 'AS'.
Does anyone have a clue?
EXEC doesn't allow string manipulations (or any expression evaluation). Define the value beforehand:
DECLARE #filename VARCHAR(MAX);
SET #filename = 'C:\Import\'+CAST((select workingdate from system..tmpworkingdate) AS VARCHAR(10))+'\Transaction(BP)';
EXEC master..xp_fileexist (#filename);
That said, you should use CONVERT() or FORMAT() to be sure you get the format you really want. You wouldn't want system changes to totally break this code.
EDIT:
Argg! I didn't realize that EXEC master..xp_fileexist doesn't even allow string variables on the execution line. So, you have to do the whole thing as dynamic SQL:
DECLARE #sql NVARCHAR(MAX) = 'EXEC master..xp_fileexist ''' + #filename + '''';
EXEC(#sql);
(There are examples on the web that do use variables, so maybe this depends on the SQL Server version.)

Stored procedure for a login with user and password as parameter

create procedure createacc(
#loginnaam nvarchar(30),
#wachtwoord nvarchar(30))
AS
CREATE LOGIN #loginnaam
WITH PASSWORD = #wachtwoord
CREATE USER #loginnaam FOR LOGIN #loginnaam
ALTER ROLE db_datareader ADD #loginnaam
Go
This gives me syntax errors while it works fine outside of the Stored Procedure.
Msg 102, Level 15, State 1, Procedure createacc, Line 5
Incorrect syntax near '#loginnaam'.
Msg 319, Level 15, State 1, Procedure createacc, Line 6
Incorrect syntax near the keyword 'with'. If this statement is a common table expression, an xmlnamespaces clause or a change tracking context clause, the previous statement must be terminated with a semicolon.
Msg 156, Level 15, State 1, Procedure createacc, Line 8
Incorrect syntax near the keyword 'ADD'.
I would suggest using dynamic sql for this. Declare a nvarchar variable, put your statement inside it and execute that statement.
For example in your case:
DECLARE #statement NVARCHAR(MAX)
SET #statement = 'CREATE LOGIN ' + #loginnaam + ' WITH PASSWORD = '''+ #wachtwoord + ''' ;'
exec (#statement)
Above answer may be velnarable to SQL injection, it is concating SQL statement and then executing it.
Is there any way to pass password string as a parameter like example below
declare #query nvarchar(500)
declare #params nvarchar(500)
declare #passwordVal nvarchar(100)
set #passwordVal=N'Test#123'
set #query = 'Alter LOGIN [SqlUser] WITH password=#pass'
set #params = N'#pass NVARCHAR (100)';
EXECUTE sp_executesql #query,#params, #pass=#passwordVal
This query generates error
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near '#pass'.
Better alternative answer to parameter is here
I am trying to create a stored procedure to create a login and a database user?

Return string with dynamic SQL

I am using SQL Server 2008 and I have a variable #sqlFinal which is of type Varchar(500).
I fill the variable as the stored procedure runs. I want to dynamically return what is in the string to show the results
SELECT #sqlFinal = 'SELECT #Error_Return AS Final_Report'
--PRINT #sqlFinal
EXEC (#sqlFinal)
But I get the following error
Msg 137, Level 15, State 2, Line 1
Must declare the scalar variable "#Error_Return".
I am assuming that #Error_Return is in the same scope as #SqlFinal?
If you just need to return the contents of #Error_Return, you can just execute this line:
SELECT #Error_Return as Final_Report
... making it a static SQL line rather than a dynamic one.
But if that's not acceptable, you may have to use sp_executeSQL instead. This allows you to pass variables to the line you're executing.
Declare #Error_Return VARCHAR(10)
Set #Error_return= 'Whatever'
exec sp_executesql N'SELECT #Error_Return as Final_Report', N'#Error_Return varchar(10)', #Error_Return
The EXEC() function creates a new execution scope. Variables, like #Error_Return, that are defined in the the current scope will not be available in the Exec() function. Look into sp_executesql instead.

Can not get ##ERROR after EXEC() with Error

Please see the following t-sql code
DECLARE #iError INT
EXEC('select * from sysobj')
SELECT #iError = ##ERROR
PRINT 'Error = ' + CAST(#iError AS VARCHAR(10))
After I run it, it returns error message, which is what I want.
Msg 208, Level 16, State 1, Line 1
Invalid object name 'sysobj'.
Error = 208
However, if I change the query
DECLARE #iError INT
EXEC('select * from sysobjects where ''c'' = 1')
SELECT #iError = ##ERROR
PRINT 'Error = ' + CAST(#iError AS VARCHAR(10))
The output will be
Msg 245, Level 16, State 1, Line 1
Conversion failed when converting the varchar value 'c' to data type int.
The problem is any code afer EXEC() is not executed.
In the real stored procedure, I have some code to handle the errors after PRINT. And none of those code executed in second case.
Could someone let me know why this happens?
I tested it on both SQL Server 2008 and 2005.
Thanks
Different errors will have different levels of abort and some of these can be controlled through the use of settings, like ARITHIGNORE and ANSI_WARNINGS.
I suggest reading the following article that explains all of this in great detail.
http://www.sommarskog.se/error-handling-I.html#whathappens
Statement-termination and Batch-abortion
These two groups comprise regular run-time errors, such as duplicates in unique
indexes, running out of disk space etc. As I have already have discussed, which
error that causes which action is not always easy to predict beforehand. This
table lists some common errors, and whether they abort the current
statement or the entire batch.
Look into implementing TRY...CATCH for your error handling. You should be able to put all of your error handling in the CATCH block then.
There's an article on this on msdn here. It has to do with the context in which the EXEC() statement is run. If you include the error trap in the parameter passed to EXEC(), you can stuff it into a temp table and then look at that.
Here's their example:
DECLARE #cmd VARCHAR(1000), #ExecError INT
CREATE TABLE #ErrFile (ExecError INT)
SET #cmd = 'EXEC GetTableCount ' +
'''pubs.dbo.authors''' +
'INSERT #ErrFile VALUES(##ERROR)'
EXEC(#cmd)
SET #ExecError = (SELECT * FROM #ErrFile)
SELECT #ExecError AS '##ERROR'

how to pass tablename as parameter in sql server

hello frnds i need to pass a table name as parameter to stored procedure
CREATE PROCEDURE six #tablename nvarchar
AS
SELECT * FROM + #tablename
Go
exec six Entry_sixsigma_mag
it gives error like
Msg 102, Level 15, State 1, Procedure six, Line 3
Incorrect syntax near '+'.
Msg 208, Level 16, State 1, Procedure six, Line 3
Invalid object name '#sixsigma'.
Try something like
CREATE PROCEDURE six #tablename nvarchar(100)
AS
EXEC('SELECT * FROM ' + #tablename)
Go
exec six Entry_sixsigma_mag
Have a look at EXECUTE (Transact-SQL)
But you should also have a look at
SQL Injection
Dynamic SQL & SQL injection
before using this blindly.