Create trigger in CREATE DATABASE stored procedure - sql

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);

Related

Dynamic SQL Server Nested EXEC

I'm trying to EXEC a stored procedure inside an nvarchar that I a them executing.
I receive the following error, Msg 2812, Level 16, State 62, Procedure Map.AdminServiceLoad, Line 127 [Batch Start Line 2]
Could not find stored procedure ''.
The stored procedures I am referencing exist, I had re-started MSSQL, am I unable to EXEC with an EXEC ?
DECLARE #NewStoredProc nvarchar(max) = '
create procedure [Map].[Load'+#TableName+']
as
begin
DECLARE #MapTable nvarchar(100) = [Map].['+#TableName+']
DECALRE #MapDevlTable nvarchar(100) = [MapDevl].['+#TableName+']
DECLARE #ShapesAreValid bit
DECLARE #PointsAreValid bit
EXEC #ShapesAreValid = Map.AdminServiceValidateShapes #TableName = #MapDevlTable
EXEC #PointsAreValid = Map.AdminServiceValidatePoints #TableName = #MapDevlTable
if(#ShapesAreValid = 1 and #PointsAreValid = 1)
begin
INSERT INTO [Map].['+#TableName+'] SELECT('+#ColsToLoad+') FROM [MapDevl].['+#TableName+']
end
end
'
EXEC #NewStoredProc
return 1
It would need to be EXEC(#cmd) not EXEC #cmd.
Without the parentheses it looks to find a stored procedure with the same name as the string inside #cmd.

run script in multiple Dbs query return error

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?

Alter Database Statement in DDL Trigger

I am trying to alter database through a DDL trigger which will fire on creation. However I am getting a below error.
CREATE TRIGGER ddl_trig_database
ON ALL SERVER
FOR CREATE_DATABASE
AS
declare #dbname as nvarchar(100)
declare #sql as nvarchar(max)
select #dbname =
CAST(eventdata().query(
'/EVENT_INSTANCE/DatabaseName[1]/text()'
) as NVarchar(128))
select #sql = N'SET IMPLICIT_TRANSACTIONS OFF
ALTER DATABASE ' + #dbname+ N' SET COMPATIBILITY_LEVEL = 110
SET IMPLICIT_TRANSACTIONS ON'
exec (#sql)
GO
create database test
Error:
Msg 226, Level 16, State 6, Line 22
ALTER DATABASE statement not allowed within multi-statement transaction.
The statement has been terminated.
I am on SQL Server 2014 on Windows 2012.
If you want a specific compatibility level for each new database created - just set that compatibility level in the model database which is the "template" for all new databases being created ...
No need for a system-level trigger for this ....
I realized the DDL trigger will be on its own transaction and Alter is not allowed if a transaction is already started. So to workaround with this problem I have created SQL Job. and put the Alters in the Job and modified the Trigger to call msdb..start_sql_job.
--Trigger
CREATE TRIGGER ddl_trig_database
ON ALL SERVER
FOR CREATE_DATABASE
AS
exec msdb..sp_start_job 'Initialize Database'
GO
--Job
declare #dbname as nvarchar(100)
declare #sql as nvarchar(max)
select top 1 #dbname = name from sys.databases
where name like 'gtp%' and create_date >= getdate() - .08
order by create_date desc
IF #dbname is not null
begin
select #sql = N'ALTER DATABASE ' + #dbname+ N' SET COMPATIBILITY_LEVEL = 110'
exec sp_executesql #sql
print 'Altered database'
end
print 'completed'

Msg 2812 : "Create Table Using Dynamic Script"

I wanted to create a table using dynamic SQL.
If I creates a table using
CREATE Table TodayTemp(id varchar(20))
DROP TABLE TodayTemp
Then there is no problem. It works fine. But problem using this is I can't create columns dynamically. Hence I tried using store create script in a variable and then finally execute them using EXEC command.
Like
Declare #CreateTableCmd varchar(max)
SET #CreateTableCmd = 'CREATE Table TodayTemp(id varchar(20))'
Exec #CreateTableCmd
But this causes an error
Msg 2812, Level 16, State 62, Line 6
Could not find stored procedure 'CREATE Table TodayTemp(id varchar(20))'.
Add parentheses around your variable when executing
Declare #CreateTableCmd varchar(max)
SET #CreateTableCmd = 'CREATE Table TodayTemp (id varchar(20))'
Exec (#CreateTableCmd)
^---------------^--------here
SQLFiddle demo
if you want to exec your script with exec, call it like this:
Exec (#CreateTableCmd)
Another way to do this is to use sp_executesql stored procedure:
exec sp_executesql #stmt = #CreateTableCmd
there're many links comparing this two approaches:
https://dba.stackexchange.com/questions/4559/difference-between-exec-and-sp-executesql-with-no-parameters
http://www.sqlskills.com/blogs/kimberly/exec-and-sp_executesql-how-are-they-different/
Declare #CreateTableCmd varchar(max)
SET #CreateTableCmd = 'CREATE Table TodayTemp'
Exec (#CreateTableCmd)
That should do the trick
Raj

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!