Can't create database using variable with SQL Server - sql-server

I want to create databases in SQL Server 2012 with this script
DECLARE #userdb varchar(30)
SET #userdb = 'DB_testing'
CREATE DATABASE #userdb
but I get this error message
Msg 102, Level 15, State 1, Line 3
Incorrect Syntax near '#userdb'
What am I doing wrong?

you have to use dynamic SQL
declare #userdb varchar(30)
SET #userdb = 'DB_testing'
declare #sql nvarchar(111);
set #sql = 'create database '+ #userdb
Exec (#sql)

You can either use dynamic SQL as shown in the other answers or you can use SQLCMD.
:SETVAR userdb "DB_testing"
CREATE DATABASE $(DB_userdb)

You can not pass variable into basic CREATE DATABASE statement, you will need dynamic SQL
declare #sql varchar(30) #userdb varchar(30)
SET #userdb = 'DB_testing'
SET #sql = 'create database ' + QUOTENAME(#userdb)
exec (#sql)

Related

Query to Copy Table Data from local database to linked server database

I am trying to copy all rows of a table from the database of my local machine to linked server database.
This is the query I am using:
DECLARE #Qry nvarchar(MAX)
DECLARE #Server nvarchar(50)
SET #Server = '[LINKEDSERVER]'
SET #Qry = '
DECLARE #Qry2 nvarchar(max)
SET #Qry2 = N''
SET IDENTITY_INSERT RDB.dbo.Type ON
insert into RDB.dbo.Type (id, Name) Select ID,Name From
[LOCALSERVER].localdb.dbo.Type
SET IDENTITY_INSERT RDB.dbo.Type OFF''
EXEC ' + #Server + '.RDB.dbo.sp_executesql #Qry2'
EXEC SP_EXECUTESQL #Qry
But I am getting this error - please help what to do here to make it work:
Could not find server 'LOCALSERVER' in sys.servers. Verify that the correct server name was specified. If necessary, execute the stored procedure sp_addlinkedserver to add the server to sys.servers.
and If remove the [LOCALSERVER] then I get:
Invalid object name 'localdb'.
Please help if any other dynamic query can work to copy table data from local server to linked server.
You are trying to run the sql statement in remote linked server. In that remote linked server, there is no linkedserver(entry in sys.servers) defined for your local server. Hence, you are getting the error.
You can define linked server for your server in the remote machine and execute statement.
DECLARE #Qry nvarchar(MAX)
DECLARE #Server nvarchar(50)
SET #Server = '[LINKEDSERVER]'
SET #Qry = '
DECLARE #Qry2 nvarchar(max)
SET #Qry2 = N''
SET IDENTITY_INSERT RDB.dbo.Type ON
insert into RDB.dbo.Type (id, Name) Select ID,Name From
[LOCALSERVER].localdb.dbo.Type
SET IDENTITY_INSERT RDB.dbo.Type OFF''
EXEC ' + #Server + '.RDB.dbo.sp_executesql #Qry2'
EXEC SP_EXECUTESQL #Qry

How to calculate the SID for new logins?

I want to create a number of database users on two sql server instances. To be able to easily copy databases from one instance to another, I want the SIDs to be consistent.
My idea was to use predictable SIDs, to minimize maintenance pain. I a dreaming about something like this:
CREATE LOGIN newuser1 WITH PASSWORD = '...', SID = CAST('newuser1' AS BINARY(16))
-- or alternatively:
CREATE LOGIN newuser1 WITH PASSWORD = '...', SID = HASHBYTES('newuser1')
Calculating values for the SID, however, seems not to be supported by the CREATE LOGIN command:
Meldung 102, Ebene 15, Status 1, Zeile 1
Falsche Syntax in der Nähe von "SID". -- Wrong syntax near "SID"
How can I use a calculated value for SID?
This can be accomplished by assembling the sql statement in a variable and the executing it with sp_executesql:
DECLARE #SQL nvarchar(4000)
SET #SQL = 'CREATE LOGIN newuser1 WITH PASSWORD = ''...'', SID = 0x'+CONVERT(VARCHAR(1000), CAST('newuser1' AS binary(16)), 2)
PRINT #SQL
EXEC sp_executesql #SQL
Alternatively, if you want to reuse this approach, you can use create a stored procedure:
CREATE PROCEDURE create_user_with_predictable_sid
#UserName varchar(256),
#Password varchar(256)
AS
DECLARE #SQL nvarchar(4000) = 'CREATE LOGIN '+#UserName+' WITH PASSWORD = '''+#Password+''', SID = 0x'+CONVERT(VARCHAR(1000), CAST(#UserName AS binary(16)), 2)
PRINT #SQL
EXEC sp_executesql #SQL
GO
GO
create_user_with_predictable_sid 'newuser1', '...'
GO
DROP PROCEDURE create_user_with_predictable_sid

Create DB Name from SELECT

I am trying to create SQL Scripts to move old data to a seperate database.
The problem I have right now is that I want to name the Database from an SELECT statement.
use DBName;
declare #release varchar(max)
set #release = concat('Release_',(select MetaRevision from metarevision))
select #release
if db_id(#release) is null create database #release
Sadly this does not work. I get the following error:
Incorrect syntax near '#release'
Is there a way to name a Database from an Select Statement?
Thanks for your help. I found a solution with the information of ta.speot.is and p.campbell.
For the future, this is the solution:
use DBName;
declare #release varchar(14)
set #release = concat('Release_',(select MetaRevision from metarevision))
declare #quoted varchar(16);
set #quoted = quotename(#release);
if db_id(#release) is null exec ('create database ' + #quoted)
You can just do it like this
declare #release varchar(max)
set #release = concat('Release_','TestOst') //Replace TestOst with your metadata
select #release
if db_id(#release) is null
declare #SQL nvarchar(max)
SET #SQL = 'create database '+quotename(#release)
exec(#SQL)

Stored procedure to alter database recovery mode isnt compiling

I am trying to create a stored procedure that would be generic. I am trying to alter a database and set the recovery mode to either simple or full. It would accept database name and mode as parameter.
The SQL query executes in the context of the master database and alters the database specified. I am trying to incorporate it via Execute SQL task in SSIS. I need the stored procedure to reside in the database that is going to perform the operation on. Not sure how that is going to work. USE database keyword is not allowed in the stored procedure...
The original query works fine but I am facing an issue while trying to execute the stored procedure in the database.It says 'RECOVERY' is not a recognized SET option.
Original query:
use master
ALTER DATABASE XYZ
SET RECOVERY FULL
Stored procedure:
USE XYZ
GO
CREATE PROCEDURE DatabaseRecoveryMode
(#mode varchar(10),
#database varchar(50))
AS
BEGIN
ALTER DATABASE #database
SET RECOVERY #mode
END
The ALTER DATABASE documentation shows the recovery model is a keyword, not a variable. You'll need to construct and execute a dynamic SQL statement for this.
CREATE PROCEDURE dbo.DatabaseRecoveryMode
(
#mode nvarchar(11),
#database sysname
)
AS
IF #mode NOT IN(N'SIMPLE', N'BULK_LOGGED', N'FULL')
BEGIN
RAISERROR('Recovery model must be SIMPLE, BULK_LOGGED, OR FULL', 16, 1);
RETURN 1;
END;
DECLARE #SQL nvarchar(MAX) = N'ALTER DATABASE '
+ QUOTENAME(#database)
+ N' SET RECOVERY '+ #mode + N';';
EXECUTE(#SQL);
GO
You need to use dynamic SQL
USE XYZ
GO
Create Procedure DatabaseRecoveryMode
(
#mode varchar(10),
#database varchar(50)
)
AS
begin
DECLARE #SQL NVARCHAR(MAX)
DECLARE #db NVARCHAR(60), #Use NVARCHAR(100)
SET #db = N'master'
SET #Use = N'Use ' + #db
SET #SQL = #Use + N' ALTER DATABASE '+ #database + N' SET RECOVERY ' + #mode ;
--SELECT #SQL
EXEC sys.sp_executesql #SQL ;
end
GO

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.

Resources