SQL server create stored procedure syntax error - sql-server

I am trying to create a simple stored procedure:
CREATE PROCEDURE SP_Test #FilePath int
AS
SELECT
LastName, FirstName
INTO
tmp_tblPerson
FROM
OPENROWSET('MSDASQL','Driver={Microsoft Access Text Driver (.txt, .csv)}','SELECT * FROM ' + #FilePath + "'")
GO
But I get a syntax error which I don't understand..?
Msg 102, Level 15, State 1, Procedure SP_Test, Line 12
Incorrect syntax near '+'.
Any ideas?

You can't use dynamic SQL when using using OPENROWSET. A workaround is to make the entire block use dynamically created SQL like this:
CREATE PROCEDURE SP_Test #FilePath int
AS
DECLARE #sql NVARCHAR(MAX) =
'SELECT LastName, FirstName
INTO tmp_tblPerson
FROM OPENROWSET(
''MSDASQL'',
''Driver={Microsoft Access Text Driver (.txt, .csv)}'',
''SELECT * FROM '' + #FilePath)'
EXEC(#sql)
As always with dynamic SQL, make sure you are not vulnerable to SQL injection attacks.
Additionally, your query appears to be incorrect as I doubt you have a table with an integer as a name.

#filepath is int, you probably want something like
'SELECT * FROM ' + convert(varchar,#FilePath)

Related

Get database name dynamically

I am trying to get the database name dynamically but, showing some errors.
What I have tried:
Declare #dbname varchar(40) = (select name from sys.databases where name like '%worksdw2019')
select db_name() as [Database], *
from #dbname.dbo.DimCustomer with (readuncommitted)
How end result should look like
select db_name() as [Database], *
from AdventureWorksdw2019.dbo.dimcustomer
These are the errors I am getting:
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near '.'.
Msg 319, Level 15, State 1, Line 3
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.
You can't parameterize database names, so you'll need dynamic SQL.
DECLARE #context nvarchar(1000);
SELECT #context = QUOTENAME(name) + N'.sys.sp_executesql'
from sys.databases
where name like N'%worksdw2019';
-- what if there is more than one?
DECLARE #sql nvarchar(max) = N'select db_name() as [Database], *
from dbo.DimCustomer;';
EXECUTE #context #sql;
Uh, with (readuncommitted) -> why? sqlblog.org/nolock
You have invalid SQL written.
You cannot write use a variable like that in SQL Server. If the database name is going to be variable as seen in your example, you will need to execute dynamic SQL using the EXEC command such as this example below:
Declare #dbname varchar(40) = (select name from sys.databases where name like '%HelloWorld')
EXEC('select db_name() as [Database], * from ' + #dbname + '.dbo.DimCustomer with (readuncommitted);')
-- you may additionally need to escape your database name
-- if you are using special characters in your name

SQL variable for Database Name

I am trying to pass a database name in as a parameter and execute some dynamic SQL. As a test I created this:
declare #HRMSDatabase_1 nvarchar(50) = N'FirstDatabase',
#Example_1 nvarchar(max) =
'select #HRMSDatabase'
execute sp_executesql #Example_1, N'#HRMSDatabase nvarchar(50)', #HRMSDatabase_1
which returns FirstDatabase as I expected.
When I try this:
declare #HRMSDatabase_2 nvarchar(50) = N'FirstDatabase',
#Example_2 nvarchar(max) =
'select
''Test''
from
#HRMSDatabase.dbo.hrpersnl hp'
execute sp_executesql #Example_2, N'#HRMSDatabase nvarchar(50)', #HRMSDatabase_2
I get an error message:
Msg 102, Level 15, State 1, Line 29
Incorrect syntax near '.'.
Is what I am trying to do possible? I cannot simply use a USE FirstDatabase as I have a few databases I have to query in the same dynamic SQL using inner joins.
Also, I cannot use SQLCMD as this script gets executed from a GUI.
Basically, I don't believe you can parameterize the database name in the table specifier. Instead try this,
DECLARE #HRMSDatabase NVARCHAR(50) = N'FirstDatabase';
DECLARE #Example3 NVARCHAR(MAX) ='SELECT
''Test''
FROM
' + QUOTENAME(#HRMSDatabase) + '.[dbo].[hrpersnl] hp';
EXEC sp_executesql #Example3;
As you'll note, it's important that the #HRMSDatabase is not recieved from user input as this would be susceptible to injection attacks.

Copy stored procedure from one database to another using T-sql

I'm using sql server
I want to copy a stored procedure from one database to another using T-sql,
but my stored procedure contains dynamic sql.
I get the definition from sys.sql_modules and execute it using this code
exec sp_executesql #sp_definition
but it gives me error:
Msg 102, Level 15, State 1, Line 23 Incorrect syntax near ' + #tblName + '
Example of my stored procedure
CREATE Procedure insertRow
(
#tblName nvarchar(250),
#value nvarchar(250)
)
AS
DECLARE #script nvarchar(1000)
SET #script='INSERT INTO '+#tblName +' VALUES('+#value+')'
exec #script
How can i escape the quotes to execute it succesfully
The solution is to escape quotes properly and using ''' instead of only one quote

Using dynamic sql in openrowset produces error

I need to create a stored procedure that gets a path as a parameter and inserts from file into table via OPENROWSET command.
After lots of searching and trying, I learned that OPENROWSET does not
support parameters and thus needs to be called with dynamic SQL.
That is the part that doesn't work, it shows me a strange error.
It could be caused by the OPENROWSET not accepting the string parameter
but - I saw many code snippets that are built similarly and users say they work.
Please help me understand what I'm missing here and how do I make this work?
Here is my code:
Declare #string varchar(MAX) = 'C:\Users\akoga_000\Desktop\test1.xlsx'
DECLARE #sqlString AS varchar(MAX)=
'insert into gameIt_DBSummer.dbo.tblUser
select * from openrowset(
''Microsoft.ACE.OLEDB.12.0'',
''EXCEL 12.0;DataBase=''
'+cast(#string as varchar(max))+'
'';Extended Properties="EXCEL 12.0 Xml;HDR=YES'',
''SELECT * FROM [Sheet1$]''
)';
EXEC (#sqlString)
//I tried also with EXEC sp_executesql and a nvarchar variable among other options
Here is the error:
Msg 102, Level 15, State 1, Line 5
Incorrect syntax near 'C:'.
I think you are getting that error because you need double extra '' character surrounding the path (#string variable). Try this:
Declare #string varchar(MAX) = 'C:\Users\akoga_000\Desktop\test1.xlsx'
DECLARE #sqlString AS varchar(MAX)=
'insert into gameIt_DBSummer.dbo.tblUser
select * from openrowset(
''Microsoft.ACE.OLEDB.12.0'',
''EXCEL 12.0;DataBase=''''
'+#string+'
'''';Extended Properties="EXCEL 12.0 Xml;HDR=YES'',
''SELECT * FROM [Sheet1$]''
)';
select #sqlString

Give DROP PROCEDURE a parameter

I'm using SqlServer for the first time, and in every single one of our create procedure scripts there is a block of code like below to remove the procedure if it already exists:
IF EXISTS (SELECT *
FROM information_schema.routines
WHERE routine_name = 'SomeProcedureName'
AND routine_type = 'PROCEDURE'
BEGIN
DROP PROCEDURE SomeProcedureName
END
//then the procedure definition
To stop cutting and pasting this boilerplate code in every file I would like to put this code in its own stored procedure so that instead the scripts would look like this:
DropIfRequired('SomeProcedureName')
//then the procedure definition
My attempt at a solution is:
CREATE PROCEDURE DropIfRequired
(
#procedureName varchar
)
AS
IF EXISTS (SELECT * FROM information_schema.routines
WHERE routine_name = #procedureName
AND routine_type = 'PROCEDURE')
BEGIN
DROP PROCEDURE #procedureName
END
But I then get the following error:
Msg 102, Level 15, State 1, Procedure DeleteProcedure, Line 10
Incorrect syntax near '#procedureName'.
Any ideas how to do what I want?
The full answer is:
DECLARE #SQL VARCHAR(8000)
SELECT #SQL = 'USE ' + DB_NAME() + CHAR(10)
SET #SQL = #SQL + 'DROP PROCEDURE ' + #procName
--PRINT #SQL
EXEC(#SQL)
The one given by Andrew will only work if the default database for your login is set to the database you want. When using dynamic sql you get a new database context. So if you do not have a default database set you will execute the command from master.
One thing to note is that in the DropIfRequired procedure, you have defined the procedure name as follows:
CREATE PROCEDURE DropIfRequired
(
#procedureName varchar
)
You need to define a length of the varchar parameter, otherwise SQL will assume a length of one character. Instead, do something like as follows (1000 should be more than enough for most procedure names)
CREATE PROCEDURE DropIfRequired
(
#procedureName varchar(1000)
)
its missing quotes, try adding them in with an exec statement.
EXEC( 'DROP PROCEDURE ''' + #procName + '''') ( all single quotes)

Resources