Passing a variable into sp_helptext - sql

We want to dynamically pass variables into sp_helptext but because sp_helptext accept a variable passed into the colon; this is causing an error.
My query looks like so:
EXEC sp_helptext N'DatabaseName.dbo.SpName'; --- this works
DECLARE #spName VARCHAR(120) = 'spName'
EXEC sp_helptext N'DatabaseName.dbo.'+#spName+''
And the error:
Msg 102, Level 15, State 1, Line 53
Incorrect syntax near '+'.

The problem is that string operations are not supported for arguments.
This is easy enough to fix. Just do the string operations before the call:
DECLARE #spName VARCHAR(120) = 'spName';
DECLARE #fullName NVARCHAR(MAX) = N'DatabaseName.dbo.' + #spName;
EXEC sp_helptext #fullName;
This is for demonstration. If you are actually passing such values in, then you should be using QUOTENAME().

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.

Dynamic Function Issue

I am trying to create some dynamic DDL to build a function and when I run it, it keeps giving me an error. I am not sure what I am doing wrong with the format....I have tried a lot of different things and now it is just out of curiousity that I want to understand how to get it to work. Any input is greatly appreciated.
CODE:
DECLARE #SQL nvarchar(max) =
'ALTER FUNCTION dbo.GetFiscalDate()
RETURNS DATETIME
AS
BEGIN
DECLARE #RESULT DATETIME
SELECT #RESULT = #FY
RETURN #RESULT;
END'
,#FY datetime = '01/01/2016'
,#ParamDef nvarchar(50) = N'#FY datetime'
exec sp_executesql #SQL,#ParamDef,#FY
Gives me this error:
Msg 156, Level 15, State 1, Line 1
Incorrect syntax near the keyword 'FUNCTION'.
Msg 178, Level 15, State 1, Line 7
A RETURN statement with a return value cannot be used in this context.
This Code however...works:
DECLARE
#FY nvarchar(10) = '01/01/2015'
,#SQL nvarchar(max)
Select #SQL =
'ALTER FUNCTION dbo.GetFiscalDate()
RETURNS DATETIME
AS
BEGIN
DECLARE #RESULT DATETIME
SELECT #RESULT = ' + #FY + '
RETURN #RESULT;
END'
exec sp_executesql #SQL
What am I missing with this when I want to pass in params instead of concatenating them with the statement?
As usual I greatly appreciate all input.
Thanks,
S
parameters are used in execution plans so that you can reuse the execution plan, not in DDL statements, use your 2nd approach
I don't see where in your string you're including a call to your function.
Whatever sql you put in your string should exec directly in a query window, and altering a function and then listing the params wouldn't do it. You have to exec the function with the params listed in their normal syntax.
Why not pass the #FY variable as a parameter into the function?
I'm not sure what you're trying to do, but I wouldn't expect the approach you've described above to work.

Use database dynamically

This execution is giving me the following error:
Msg 102, Level 15, State 1, Line 5
Incorrect syntax near 'go'.
Msg 111, Level 15, State 1, Line 11
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
If i remove the "GO" it gives me just the second one.
Any hints of what am I missing?
declare #dbname varchar(500)
set #dbname='master'
Exec ('
Use ' + #dbname + '
go
create PROCEDURE [dbo].[krijo_database] #dbname nvarchar(2000), #Direktoria varchar(4000)
AS
BEGIN
declare #stringu nvarchar(100)
set #stringu =
''CREATE DATABASE '' + #dbname
exec (#stringu)
End
')
Answer
declare #dbname varchar(500)
set #dbname='kontabel'
Exec(
'Use ' + #dbname +'
Exec (''
create PROCEDURE [dbo].[krijo_database] #dbname nvarchar(2000), #Direktoria varchar(4000)
AS
BEGIN
declare #stringu nvarchar(100)
set #stringu =
''''create DATABASE '''' + #dbname
exec (#stringu)
End
'')
')
Actually I tried like this and it worked but I had to change quotes.
The real procedure that I would like to use is more than 50000 lines and I can't go and manually change the quotes to everything.
Is there a better way?
Two issues:
Using "GO" is incorrect... there is no SQL keyword called "GO"... that's just a hack that SQL Server Management Studio is performing for you.
You need to the CREATE PROCEDURE command in it's own context... simple.
Here's the slight modification to your script:
declare #dbname varchar(500)
set #dbname='master'
Exec ('
Use ' + #dbname + '
EXECUTE(''create PROCEDURE [dbo].[krijo_database] #dbname nvarchar(2000), #Direktoria varchar(4000)
AS
BEGIN
declare #stringu nvarchar(100)
set #stringu =
''''CREATE DATABASE '''' + #dbname
exec (#stringu)
End'')
')
So the answer is to put another "EXECUTE" command inside the first EXECUTE command. I do this all the time, a lot of times in an "sp_msforeachdb". You can nest those bad boys as long as you want.
Sometime ago I had code which was updating database structure based on scripts.
I end up with split file by 'go' and execute separately each fragment. Can you try this?
So, first exec use statement, and than exec createprocedure.
Be sure to verify that it is created in proper database
My mistake, I didn't notice something.
maybe it's the Exec inside the Exec that's causing the error?
or because your'e assigning a nvarchar(2000) to a nvarchar(100)
"Msg 102, Level 15, State 1, Line 5 Incorrect syntax near 'go'. Msg 111, Level 15, State 1, Line 11 'CREATE/ALTER PROCEDURE' must be the first statement in a query batch. " If i remove the "GO" it gives me just the second one.
try this without any use or go: create PROCEDURE '+#dbname+'.[dbo].[krijo_database] #dbname nvarchar(2000)
You can't use GO like that
It isn't a SQL command
It tells SSMS to split the batch
If you remove it, then you'll get "first in batch" error which is expected
In this case, why not just do this...
Use master
GO
create PROCEDURE [dbo].[krijo_database] #dbname nvarchar(2000), #Direktoria varchar(4000)
AS
BEGIN
declare #stringu nvarchar(100)
set #stringu = 'CREATE DATABASE ' + #dbname
exec (#stringu)
End
GO
Why do need dynamic SQL to create a stored procedure?
USE master
GO
CREATE PROCEDURE dbo.create_database #name nvarchar(100)
AS
DECLARE #sql nvarchar(100)
SET #sql = 'CREATE DATABASE ' + QUOTENAME(#name)
EXEC (#sql)
GO
What you're after can't be done I don't think.
See this article for reference
The Real procedure that i would like to use it is a very big one, more dhan 50000 lines and i can't go on an changing the quotes to everything
Microsoft SQL Server has a maximum length of varchar of 8000 characters.
http://www.databasejournal.com/features/mssql/article.php/3788256/Data-Types-in-SQL-Server-2008.htm
you should create stored procedure with that portion with variable.
I used SQl DMO!
Great feature both for 32 and 64 bit,compatible with both SQL express and server!