DECLARE #SQL VARCHAR(100)
DECLARE #dbName VARCHAR(100)--
SET #dbName = 'somedbname'--
SET #sql = 'USE [' + #dbName + ']' + CHAR(13) + CHAR(10)
SET #sql = #sql + 'GO' + CHAR(13) + CHAR(10)-- Print the command
EXEC (#sql)
When I run this it gives error Incorrect syntax near 'GO' has someone found workaround to this?
Requirement : I need to include stored procedure creation in switched database.
GO is not a SQL statement - it is a command recognized by the SQL Server utilities (e.g. sqlcmd, osql, SQL Server Management Studio code editor).
However, you can change the database without the GO command.
Related
When I run the below code, it runs and prints the SQL output perfectly.
However the last EXEC statement throws an error
Incorrect syntax near the keyword 'TRIGGER'
The code basically strings together some SQL to create a trigger for all existing tables.
When I manually take that PRINT output at the end and execute it in SSMS it works fine, but the EXEC in the code just won't run it.
DECLARE #sql AS NVARCHAR(MAX)
SET #sql = ''
SELECT #sql = #sql + 'CREATE TRIGGER [tr_' + table_name +'] ON
[' + table_schema + '].[' + table_name + '] FOR INSERT, UPDATE, DELETE AS
SELECT 1 GO' + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.TABLES
WHERE table_type = 'BASE TABLE'
PRINT #sql; -- output is correct and I can paste this and it works
EXEC sp_executesql #sql -- doesn't work
The SQL command to execute has to be a single batch. So, you can't use GO.
You better declare a CURSOR and execute the script for each table.
I'm looking to migrate several SQL views from one database to another. Both databases definitions are identical, so I should not have to worry about compatibility issues. I will have to perform this task on several client systems so I am looking to automate it instead of using the 'Script View As' option and manually duplicating each view.
I am brand new to cursors, so I apologize if this is a terribly simple request but I have tried several approaches and gotten nowhere. My searches of this site and others have been similarly fruitless. This is what I have come up with so far:
declare #sql nvarchar(max)
declare #view nvarchar(max)
declare #dbname nvarchar(30)
set #dbname = 'DatabaseName'
DECLARE cCursor CURSOR LOCAL FOR
SELECT VIEW_DEFINITION
from INFORMATION_SCHEMA.views
where TABLE_NAME like '%MyCriteria%'
OPEN cCursor
FETCH NEXT FROM cCursor into #view
WHILE ##FETCH_STATUS = 0
BEGIN
set #sql = 'USE ' + #dbname + ' GO ' + #view
execute #sql
FETCH NEXT FROM cCursor into #view
END
close cCursor
deallocate cCursor
I am getting an error message upon execution that says:
Msg 203, Level 16, State 2, Line 17
The name 'USE DATA14 GO CREATE VIEW
.... is not a valid identifier.
where the .... represents the create view statement I fetched from Information schema.
Any ideas what I'm doing wrong?
Thanks in advance.
EDIT:
I tried another approach that does not rely on cursors and I believe I am closer, but I am still getting errors that have me baffled:
use SourceDB
go
declare #sql nvarchar(max)
set #sql = N''
select #sql = #sql + 'USE DestDB' + CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10) + s.definition + CHAR(13) + CHAR(10) + 'GO' + CHAR(13) + CHAR(10)
from sys.sql_modules as s
inner join sys.objects as o
on s.object_id = o.object_id
where o.type_desc = 'VIEW'
and s.definition like '%MyCriteria%'
exec data14..sp_executesql #sql
--select #sql
The text of the error message is:
Msg 102, Level 15, State 1, Line 2
Incorrect syntax near 'GO'.
Msg 111, Level 15, State 1, Line 3
'CREATE VIEW' must be the first statement in a query batch.
Msg 102, Level 15, State 1, Line 22
Incorrect syntax near 'GO'......
and so on and so forth for each view in the list
Another option is to use Powershell. There are many ways to do it, I personally like to make a file for each script, and I am making an assumption that the views do not already exist in the new database. So this probably will not work verbatim, but should get you pointed in the right direction.
Create an export folder on the server (C:\Temp\Views)
Open the source server in the object explorer.
Navigate to the source database (/Databases/{DatabaseName})
Right click on 'Views' and select 'Start Powershell'
Run the following command which will create a file for each view:
ls | ? { $_.name -match "MyCriteria" } | %{ $_.scriptheader(0) + $_.textbody > "C:\temp\views\$($_.Schema).$($_.name).sql" }
Import the scripts into another database with
ls "C:\temp\views" | %{ invoke-sqlcmd -inputfile $_.fullname -database "DatabaseName" }
To achieve what you're looking for, you have to nest your dynamic SQL within dynamic SQL...
DECLARE #sql nvarchar(max)
DECLARE #dbname nvarchar(30)
SET #dbname = 'DatabaseName'
SET #sql = '';
SELECT #sql = #sql + '
EXEC ' + #dbname + '.sys.sp_executesql N''' + REPLACE(VIEW_DEFINITION, '''', '''''') + ''''
FROM INFORMATION_SCHEMA.views
WHERE TABLE_NAME like '%table%'
EXEC (#sql);
There is a catch though.
The double dynamic sql needs to be double escaped. Hence the REPLACE above.
By the way... The correct syntax for executing dynamic SQL is EXEC (#SQL) -- Note the brackets
Without the brackets, you're telling the server to execute a procedure. Hence the reason for your first error
Hope that helps
I'm having issues with a dynamic SQL script in particular this bit:EXEC('
if db_id(''' + $(db) + ''') is null
BEGIN
CREATE DATABASE ' + $(db) + '
END
The if statement part seems to work fine, I know this because if the database exists then the create database line is not run but when it needs to run I just get syntax errors near that line.
I have also tried:
CREATE DATABASE ''' + $(db) + '''
with no luck
Any Ideas?
DECLARE #DB_NAME NVARCHAR(128) = N'Test_DB'
DECLARE #Sql NVARCHAR(MAX);
IF DB_ID(#DB_NAME) IS NULL
BEGIN
SET #Sql = N' CREATE DATABASE ' + QUOTENAME(#DB_NAME)
EXECUTE sp_executesql #Sql
END
Important Note
Make sure your database name is in accordance with the Rules for Regular Identifiers
I am trying to create a script to create/setup a group of stored procedures that will all be fairly similar.
So I am trying to loop through this code, changing the #DATABASE_NAME and #TableName when needed.
/* Start loop */
DECLARE #create_stored_procedure nvarchar(max)
SET #create_stored_procedure = N'
USE [' + #DATABASE_NAME + ']
CREATE PROCEDURE [dbo].[sproc_imp_' + #TableName + ']
AS
BEGIN
PRINT(''doing something'')
END'
EXEC sp_executesql #statement = #create_stored_procedure
/* End loop */
But I am getting errors saying
'CREATE/ALTER PROCEDURE' must be the first statement in a query batch.
or
'CREATE/ALTER PROCEDURE' does not allow specifying the database name as a prefix to the object name.
All the solutions online suggest using GO, but that won't work in dynamic SQL.
Does anyone know a possible solution for SQL Server 2005?
I wouldn't call the solution intuitive, but apparently this works. I prefer the look of this one though.
Try with spiting USe DB and create procedure. Like this
DECLARE #create_store_procedure nvarchar(max)
SET #create_store_procedure = N'
USE [' + #DATABASE_NAME + '] '
EXEC sp_executesql #statement = #create_store_procedure
SET #create_store_procedure = N'
CREATE PROCEDURE [dbo].[sproc_imp_' + #TableName + ']
AS
BEGIN
PRINT(''doing something'')
END '
EXEC sp_executesql #statement = #create_store_procedure
This is working perfectly for me
I tried Nithesh's answer and that didn't work for me it ended up creating the store procedure in the master table. Zec's answer worked. Creating a dynamic query inside my dynamic query.
DECLARE #create_store_procedure nvarchar(max)
DECLARE #use_db nvarchar(max)
SET #create_store_procedure = N'
CREATE PROCEDURE [dbo].[sproc_imp_' + #TableName + ']
AS
BEGIN
PRINT(''doing something'')
END '
SET #use_db = N'
USE [' + #DATABASE_NAME + ']
DECLARE #sub_create_store_procedure nvarchar(max)
SET #sub_create_store_procedure = ''' + REPLACE(#create_store_procedure, CHAR(39), CHAR(39) + CHAR(39)) + '''
EXEC sp_executesql #statement = #sub_create_store_procedure
'
EXEC sp_executesql #statement = #use_db
The following is not working and I am definitely missing the obvious but would be nice if somebody could explain why is not working. I need to change db dynamically.
The print out looks good but does not change db in the SQL Server drop down.
DECLARE #tempSql nvarchar(4000);
DECLARE #FinalSQL nvarchar(4000);
DECLARE #dbName varchar(100);
SET #dbName = 'Pubs';
SET #tempSql = 'SELECT DB_NAME()';
SET #FinalSQL = 'USE ' + #dbName + '; EXEC sp_executesql N''' + #tempSql + '''';
EXEC (#FinalSQL)
If SQLCMD mode is an option for your (within SSMS, for example), you can do this:
:setvar dbname Pubs
USE [$(dbname)]
SELECT DB_NAME()
Or, your original syntax was pretty close. Try this:
DECLARE #db AS NVARCHAR(258);
SET #db = QUOTENAME(N'Pubs');
EXEC(N'USE ' + #db + N'; EXEC(''SELECT DB_NAME();'');');
GO
There is a way to access data from a specific database by using this syntax :
FROM DatabaseName..TableName
maybe you should use a dynamic database name in your scripts, then change it whenever you need
otherwise, take a look at this : http://www.sqlteam.com/article/selecting-data-from-different-databases
Executing the dynamic SQL is done in a scope of its own.
So you do change the current database, as you see, but only within the scope of the dynamic SQL.