run script in multiple Dbs query return error - sql

I am running a query with the sp_MSforeachdb stored procedure. I used three databases which exist in my server instance: ExcelineDev, EXCE_NR1, and EXCE_AKI.
declare #t table (dbname varchar(50),ss varchar(max),sss varchar(max))
DECLARE #command varchar(max)
SELECT #command = 'IF ''?'' IN (''ExcelineDev'',''EXCE_NR1'',''EXCE_AKI'')
BEGIN USE ?
EXEC
(''
select DB_NAME(DB_ID()), category,name from usrpt.report
where name like ''''%leders%''''
'')
END'
print #command
insert into #t
EXEC sp_MSforeachdb #command
select * from #t
I'm getting the following error:
'Msg 911, Level 16, State 1, Line 2 Database 'Migration_Release_1'
does not exist. Make sure that the name is entered correctly.'
I'm confused, because there is no DB called 'Migration_Release_1' in my server instance. Why is SQL searching for this database?

Related

Linked servers, results query xp_cmdshell to table migration SQL Server 2005 to SQL Server 2019

I'm migrating procedures from Microsoft SQL Server 2005 to Microsoft SQL Server 2019 and I got stuck while trying insert query result xp_cmdshell in linked servers to table
I'm out of ideas
Old solution in Microsoft SQL Server 2005:
INSERT INTO LOGTABLE (ShopNo,Line) SELECT 1, OUTPUT FROM openquery ([IP_LINKED_SERV],'set fmtonly off; exec master..xp_cmdshell ''type d:\log\file.log'' ')
Microsoft SQL Server 2019 gives me error:
Msg 11519, Level 16, State 1, Procedure
sp_describe_first_result_set, Line 1 [Batch Start Line 0] The metadata could not be determined because statement 'exec master..xp_cmdshell 'type d:\log\file.log'' invokes an extended stored procedure.`
I found a way how to do xp_cmdshell in SQL Server 2019 at linked servers
EXEC ('set fmtonly off;exec master..xp_cmdshell ''type d:\log\file.log'' ') AT [IP_LINKED_SERV]
However I can't insert this results in table
INSERT INTO LOGTABLE (ShopNo,Line) SELECT '998', OUTPUT FROM EXEC ('set fmtonly off;exec master..xp_cmdshell ''type d:\log\file.log'' ') AT [IP_LINKED_SERV]
Incorrect syntax near the keyword 'EXEC'.
part of the procedure in sql2005:
DECLARE TableCursor CURSOR FOR
SELECT IP, SqlUser, SqlPass, Object FROM ..ObjectInfo
OPEN TableCursor
FETCH NEXT FROM TableCursor INTO #Ip, #SqlUser, #SqlPass, #Object
WHILE ##FETCH_STATUS = 0
BEGIN
PRINT #Object
SELECT #PARAMS = ' #tmp_object varchar(5) OUTPUT'
set #SQL = 'INSERT INTO LOGTABLE (Object,Line) SELECT #tmp_object, output FROM openquery (['+#Ip+'],''set fmtonly off;
exec master..xp_cmdshell ''''type d:\log\file.log''''
'')'
BEGIN TRY
EXECUTE sp_executesql #SQL,#PARAMS, #tmp_object = #Object OUTPUT
END TRY
BEGIN CATCH
INSERT INTO LOGTABLE (Object, Line) VALUES(#Object, '-error')
END CATCH```

Create trigger in CREATE DATABASE stored procedure

We have a stored procedure that creates a database for each of our customers. This stored procedure runs in the context of master. A database name is passed in as a parameter to the stored procedure.
I am trying to modify the stored procedure to add a trigger to a table. I understand the stored procedure must switch to the new database to create triggers, so have appended the following to the stored procedure:
SET #str = ('USE ' + QUOTENAME (#db_name) + ' GO
CREATE TRIGGER ...')
EXEC (#str);
I get the error
Msg 102, Level 15, State 1, Line 3
Incorrect syntax near 'GO'.
Msg 111, Level 15, State 1, Line 4
'CREATE TRIGGER' must be the first statement in a query batch.
Now I assume the second error is a consequence of the first, but I am blowed if I can work out how to switch databases in the stored procedure in order to create the triggers.
We are using SQL Server 2019. How do I create triggers in a create database stored procedure?
Another approach is to execute statement one after another.
DECLARE #str VARCHAR(MAX)
DECLARE #db_name SYSNAME = 'YourDBName'
SET #str = 'USE ' + QUOTENAME (#db_name)
EXEC (#str)
SET #str = 'CREATE TRIGGER ...'
exec (#str);
For completeness, as mentioned by #DaleK, adding the approach mentioned by Aaron Bertnard in the Stackexchange link
DECLARE #str VARCHAR(MAX)
DECLARE #db_name SYSNAME = 'master'
SET #str = 'EXEC '+ #db_name + '..sp_executesql #stmt=N''CREATE PROCEDURE usp_test AS SELECT 1;'''
exec (#str);

Execute openrowset stored procedure, parameter use

Little bit of background information:
I have a stored procedure, lets call it SP1. SP1 calls another stored procedure: SP2. SP2 calls another stored procedure: SP3.
Now, the first stored procedure (SP1) returns a resultset. The resultset are parameters for SP2, this is done with a cursor.
Because of these nested inserts and executes, i have to use an openrowset dynamic SQL string to execute my stored procedures.
This is my query:
DECLARE #P_Source varchar(255) = 'test'
DECLARE #P_Location varchar(255) = 'test'
DECLARE #sql varchar(max)
SET #sql = 'INSERT INTO #tmp
SELECT *
FROM OPENROWSET (
''SQLOLEDB'',
''Server=(local);TRUSTED_CONNECTION=YES;'',
''set fmtonly off
EXECUTE dbo.SP1
#P_Source = '''''+#P_Source+'''''''
,#P_Location = '''''+#P_Location+'''''''
)'
exec(#sql)
(I have ofcourse created the table #tmp). I have more parameters to be exact (12), all varchar, but I left them out to not make it messy.
I'm getting the following error
Msg 102, Level 15, State 1, Line 12
Incorrect syntax near ','.
am I using the openrowset command in the correct way with the corresponding procedure parameters?
All those quotes get confusing. By doing select #sql prior to the exec you can see what SQL Server is going to try and do. Based on the query you've provided #sql currently contains:
INSERT INTO #tmp
SELECT *
FROM OPENROWSET (
'SQLOLEDB',
'Server=(local);TRUSTED_CONNECTION=YES;',
'set fmtonly off
EXECUTE dbo.SP1
#P_Source = ''test'''
,#P_Location = ''test'''
)
To help you build up to the final solution you could try having a dummy SP1 that takes two numeric parameters - that'll eliminate some quotes for you to worry about. Once you have that working you can proceed to add string parameters until you get what you want.
For sql linked server use OPENQUERY
https://learn.microsoft.com/en-us/sql/t-sql/functions/openquery-transact-sql
and sp_executesql
DECLARE #P_Source varchar(255) = 'test'
DECLARE #P_Location varchar(255) = 'test'
DECLARE #SQL NVARCHAR(MAX) = '',
#QUERY NVARCHAR(MAX) = '',
#Params NVARCHAR(500) = N'DECLARE #P_Source VARCHAR(255),#P_Location VARCHAR(255); ',
#ParamsValue NVARCHAR(500) = N'SELECT #P_Source = '''''+#P_Source+''''', #P_Location = '''''+#P_Location+''''';'
SET #Query = N'set fmtonly off; EXECUTE dbo.SP1 #P_Source, #P_Location'
SET #SQL = 'SELECT * FROM OPENQUERY([Local],'' sys.sp_executesql ' + #Params + #ParamsValue + #Query +''' )'
INSERT INTO #Tmp
EXEC (#SQL)

Execute dynamic sql for all rows in a result set without a loop

I have a query that generates a query for each row in a table.
For example:
select ' create proc ['+[ProcName]+'] as
print '''+[ProcName]+''''
from MyTable
The results of this query will give me a sql statement I can execute for every row of data in the table.
CREATE PROC [proc_1]
AS
PRINT 'proc_1'
--
CREATE PROC [proc_2]
AS
PRINT 'proc_2'
etc.
Is it possible to execute every row in my result set without having to implement some form of cursor/loop?
You can concatenate all column values in sql pass variable by many ways
as examples: XMLPATH, STUFF or COALESCE, with some manipulation with string.
but still getting an error
The Main Issue for This task is Go
Go is Not-Valid T-SQL
so if you tried execute dynamic sql contains Go, the next error will be raised:-
Msg 102, Level 15, State 1, Line 4 Incorrect syntax near 'go'.
After surfing the stackoverflow , I get the resolved here:-
Execute Dynamic Query with go in sql
so Get the next demo (after applying the above link with my trials):-
Demo:-
-- Try to create 4 procedures proc_1, proc_2 , proc_3 and proc_4
Create database Demo
go
use Demo
go
Create table MyTable (procName varchar (200))
go
insert into MyTable values ('proc_1')
go
insert into MyTable values ('proc_2')
go
insert into MyTable values ('proc_3')
go
insert into MyTable values ('proc_4')
go
declare #Query nvarchar(max)
SELECT #Query = isnull(#Query,'') + 'create proc ['+[ProcName]+'] as
print '''+[ProcName]+''''+ char (10) + '
Go
'
FROM MyTable
--print #Query
SET #Query = 'EXEC (''' + REPLACE(REPLACE(#Query, '''', ''''''), 'GO', '''); EXEC(''') + ''');'
EXEC (#Query)
Result:-
you can declare a variable, store the queries (seperates) inside it and execute it
DECLARE #strQuery Varchar(MAX)
SET #strQuery = ''
select #strQuery = #strQuery +
'EXEC('' create proc [' + [ProcName] + ']
as
print ''''' + [ProcName] + '''''
'')'
from MyTable
EXEC(#strQuery)
--To view your query
PRINT(#strQuery)
Note: i used Exec command for each procedure because they cannot be executed at the same time in a query

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!