Creating schema for all databases in Sql Server - sql

I have problems creating schema for all databases on a sql server in one script.
declare #ssql varchar(2000)
set #ssql= 'use [?]
GO
CREATE SCHEMA [sp_schema]'
exec sp_msforeachdb #ssql
go
But I am always getting these errors:
Incorrect syntax near 'GO'.
'CREATE SCHEMA' must be the first statement in a query batch.
And if I use another statement like CREATE USER => everything works fine.
Any ideas?
Thanks.
Ok
I found it.
It should be like this:
declare #ssql varchar(2000)
set #ssql= 'use [?]
EXEC (''CREATE SCHEMA [sp_schema]'')'
exec sp_msforeachdb #ssql
go
And it works!!
Thanks Dan for your contribution!

GO is not actually a SQL Server command. It is used as a batch separator in applications like SQL Server Management Studio.
I think you can just remove the GO.
Otherwise, this should work:
declare #ssql varchar(2000);
set #ssql= '
use [?]
declare #sql varchar(100)=''create schema [sp_schema]''
exec(#sql)
'
exec sp_msforeachdb #ssql;

Related

How to use sp_helptext with schema without quotes (for query shortcuts)

All my procedures, views are in schema xx. I know I have to use quotes in this case and when I run
exec sp_helptext 'xx.my_procedure'
it works fine.
However I would love to use query shortcuts (I am using SSMS 16) for sp_helptext.
When I select text and run shortcut I am getting:
Incorrect syntaxt near '.'
which is obviously due to missing quotes in selected text.
Is there a way to workaround this?
Probably something that could temporarily add quotes via simple shortcut? Or maybe some other procedure that would nest sp_helptext and fix the input?
Maybe there are another approaches for achieving your target,
but mine is as following:-
Create a procedure that executing SP_HELPTEXT after override it.
assuming the scema name is XX
Create procedure usp_helptext (#myObject varchar(255))
as
begin
declare #Query nvarchar(1000)
set #Query = 'exec sp_helptext ''XX.' + #myObject + ''''
print #Query
exec (#Query)
end
and execute the created proecure as next:-
exec usp_helptext proc_name.
Finally use a shortcut for usp_helptext rather than sp_helptext.

EXEC to USE Database

I have written a script that generates a database backup file name, backs up the database, and then restores it as a copy with the new database name. The name is based on some date/time data.
I then need to USE that database, in the script, and then disable all triggers.
However, this doesn't work:
DECLARE #Use VARCHAR(50)
SET #Use = 'USE ' + #NewDatabaseName
EXEC(#Use)
Running it manually - the database doesn't get 'USED'.
How can I execute the USE statement with a variable?
I have tried the sp_executesql proc as well, with the same result. Database didn't change.
DECLARE #sqlCommand nvarchar(1000)
SET #sqlCommand = 'USE ' + #NewDatabaseName
EXECUTE sp_executesql #sqlCommand
Looks like I might need to go into sqlcmd mode? Really hoping not to, though.
Both exec and execute_sql run in their own scope. And the change in database will only affect their own scope. So you could:
set #sql = 'use ' + quotename(#new_db_name) + '; disable trigger t1;'
exec (#sql)
As far as I know, there is no way to change the database context of the current scope to a variable database name.

stored procedure receiving DB name to work with

I am looking to write a stored procedure which received a database name along with other parameters, and the stored procedure needs to work on the Database which it received
any thoughts please
Something like the following should work, as long as correct permissions are setup:
CREATE PROCEDURE dbo.sptest
#DB VARCHAR(50)
AS
BEGIN
DECLARE #sqlstmt VARCHAR(MAX)
SET #sqlstmt='SELECT TOP 10 * FROM ' + #DB + '.dbo.YourTableName'
sp_executesql #sqlstmt
END
GO
As mentioned, be very careful when using dynamic SQL like this- only use with trusted sources because of the ability to wreck havoc on your DB. At a minimum, you should add some checking of the value of #DB passed in to make sure it matches a limited list of database names that it will work with.

SQL Script to take a Microsoft Sql database online or offline?

If I wish to take an MS Sql 2008 offline or online, I need to use the GUI -> DB-Tasks-Take Online or Take Offline.
Can this be done with some sql script?
ALTER DATABASE database-name SET OFFLINE
If you run the ALTER DATABASE command whilst users or processes are connected, but you do not wish the command to be blocked, you can execute the statement with the NO_WAIT option. This causes the command to fail with an error.
ALTER DATABASE database-name SET OFFLINE WITH NO_WAIT
Corresponding online:
ALTER DATABASE database-name SET ONLINE
-- Take all user databases offline
CREATE PROCEDURE SP_TakeOfflineAllDatabase AS
BEGIN
DECLARE #db sysname, #q varchar(max);
DECLARE cur_db CURSOR FOR
SELECT name FROM sys.databases WHERE owner_sid<>0x01;
OPEN cur_db;
WHILE 1=1
BEGIN
FETCH NEXT FROM cur_db INTO #db;
IF ##FETCH_STATUS <> 0
BREAK;
SET #q = N'ALTER DATABASE [' + #db + N'] SET OFFLINE WITH NO_WAIT';
EXEC(#q);
END;
CLOSE cur_db;
DEALLOCATE cur_db;
END;
Restart the server before run the procedure. It will close the existed connections to the databases.
I know this is an old post but, just in case someone comes across this solution and would prefer a non cursor method which does not execute but returns the scripts.
I have just taken the previous solution and converted it into a select that builds based on results.
DECLARE #SQL VARCHAR(8000)
SELECT #SQL=COALESCE(#SQL,'')+'ALTER DATABASE '+name+ N' SET OFFLINE WITH NO_WAIT;
'
FROM sys.databases
WHERE owner_sid<>0x01
PRINT #SQL
Here's a note that just might be very usefull to you :
It's almost always possible to see what the GUI is doing TSQLwise behind the scenes.
c : http://www.mssqltips.com/tip.asp?tip=1505

Using Environment variables in T-SQL

How can I read the value of a system environment variable in a T-SQL script?
This is to run on SQL Server 2005.
To "read the value of a system environment variable in a T-SQL script" you can set SQL Management Studio to use "sqlcmd Mode".
Then you can use like this:
Print '$(TEMP)'
:r $(Temp)\Member.sql
go
I'm not sure how this is done outside of "SQL Management Studio" but it should be hard to find out.
This should give you a list (provided you allow people to execute xp_cmdshell)
exec master..xp_cmdshell 'set'
Note: xp_cmdshell is a security hazard ...
You could also do this with a managed stored proc an extended stored proc or via a com component.
Hey, if you want to get the server name, just call SELECT ##SERVERNAME
xp_cmdshell is generally best avoided for security reasons.
You're better off using a CLR assembly. Here's a good introduction to creating a CLR assembly.
You can use System.Environment.GetEnvironmentVariable() in C# - you'll find more info on how to do that here.
Thanks for the answers.
They helped me get to a working solution, although this is probably not the most advanced method:
declare #val varchar(50)
create table #tbl (h varchar(50))
insert into #tbl exec master..xp_cmdshell 'echo %computername%'
set #val = (select top 1 h from #tbl)
drop table #tbl
Specifically I was trying to get the hostname, the echo %computername% could be replaced with the hostname system command. But this now works for any environment variable.
To determine a specific environment variable in T-SQL (MS SQL Server) you can do something like:
Grant Security Permissions
use [master]
execute sp_configure 'show advanced options', 1
reconfigure
go
execute sp_configure 'xp_cmdshell', 1
reconfigure
go
grant execute on xp_cmdshell to [DOMAIN\UserName]
grant control server to [DOMAIN\UserName]
go
Source: https://stackoverflow.com/a/13605864/601990
Use Environment Variables
-- name of the variable
declare #variableName nvarchar(50) = N'ASPNETCORE_ENVIRONMENT'
-- declare variables to store the result
declare #environment nvarchar(50)
declare #table table (value nvarchar(50))
-- get the environment variables by executing a command on the command shell
declare #command nvarchar(60) = N'echo %' + #variableName + N'%';
insert into #table exec master..xp_cmdshell #command;
set #environment = (select top 1 value from #table);
-- do something with the result
if #environment = N'Development' OR #environment = N'Staging'
begin
select N'test code'
end
else
begin
select N'prod code'
end
Also remember to restart the SQL Server Service when changing the Environment Variables.