Microsoft SQL Stored Procedure - sql

I am new to sql. I would like to ask what should I do when I will create a database using a stored procedure.
I usually do this to create database: create databse db_mydatabase
a database name db_mydatabse will be created.
Question: how will I able to create a database using stored procedure?

Use this
create procedure sp_create_db #name nvarchar(500)
as
begin
declare #sql nvarchar(max);
set #sql='CREATE DATABASE '+#name;
EXECUTE(#sql)
end

Related

Stored procedure execution order

Thanks for your time, is there a way to execute the create database part of the statement before the use database name?
I guess I could create 2 set and execute statements but there must be a better way ?
CREATE PROCEDURE [dbo].[Master]
#DBNAME NVARCHAR(50)
AS
DECLARE #CODE NVARCHAR(MAX)
SET #CODE = 'CREATE DATABASE '+#DBNAME+'; USE '+#DBNAME
EXEC SP_Executesql #CODE
Thanks in advance

How to create a simple stored procedure with table name as an input

I am using SQL Server 2017 and I would like to create a stored procedure with a single table name as an input variable. All I want the procedure to do is update that table in a variety of ways. This project will be done twice a year, and the columns will always be the same, so I would like to try this as a stored procedure, so I do not have to highlight several lines of code and executing each time.
Is there a simple way to pass a table name through a stored procedure which updates the table (adding columns, calculating columns, replacing nulls in columns etc). In a basic example, one task would be just replaces nulls with 0s in a column. I am not sure how to set this up though. DO I have to declare every column in the table too?
CREATE PROCEDURE updteleform
#tablename TABLE
AS
BEGIN
UPDATE #tablename
SET Recog = 0
WHERE Recog IS NULL
END
GO
I'm assuming you want to update a physical table. SQL Server table variables don't work that way, rather they are a way to pass a transient result set to a stored procedure. There is no persistence if your stored procedure does not do so.
If you are looking to update the same table, then just write the procedure to work on that table.
If you are looking to update multiple tables using the same script then you should change your procedure to accept a string parameter that would be the name of the table you want it to work on and then use dynamic SQL in your stored procedure.
Something like
CREATE PROCEDURE updteleform #tablename sysname
AS
BEGIN
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'
update ' + QUOTENAME(#tablename) + '
set Recog= 0
where Recog is null;';
EXEC sp_executesql #sql;
END
GO
And then call it with something like:
EXEC updteleform #tablename = 'table1';
EXEC updteleform #tablename = 'table2';
EXEC updteleform #tablename = 'table3';
...

Dynamic change schema in SQL procedure

I have a database with multiple schemas. In every schema I got table called [Logs], so my database tables looks like:
[s1].[Logs]
[s2].[Logs]
[s3].[Logs]
...
[sN].[Logs]
Every day I would like to run stored procedure, which will do same operations on every above table. Is there a way to pass schema name into stored procedure? I am using SQL on Azure.
No, it is not - unless the SP Uses then dynamic SQL to execute some SQL String you constructed in the SP.
This happens via the sp_executesql stored procedure
http://technet.microsoft.com/en-us/library/ms188001.aspx
has more information.
Microsoft has a few undocumented procedures that perform "foreach" operations on tables (sp_msforeachtable) and databases (sp_msforeachdb). Both of these rely on another undocumented proc called sp_msforeachworker which you might be able to exploit to create a foreachschema type of routine. Theres an article (reg required) here that demonstrates this approach.
That said, its unlikely Azure supports anything of these, so you might have to fashion your own using a crude loop:
declare #schemas table (i int identity(1,1), name sysname);
insert into #schemas
select name from sys.schemas where name like 's[0-9]%';
declare #i int, #name sysname, #cmd nvarchar(max);
select #i = min(i) from #schemas;
while #i is not null
begin
select #name = name from #schemas where i = #i;
set #cmd = replace(N'select count(*) from [{0}].[Logs];', '{0}', #name);
print #cmd;
--exec(#cmd);
select #i = min(i) from #schemas where i > #i;
end

Parametrizing input using sql server?

I want to parametrize my stored procedure's input to prevent sql injection. The problem is MY database has no application(It's just for school) & as there's no client language like C# etc, I have to do it with sql itself. i did this
ALTER procedure [dbo].[drop_tt]
#ss varchar(40)
as
EXEC sp_executesql N'SELECT *
FROM tt
whERE ss = #Ss', N'#ss varchar(40)', #ss
but when I execute this statement the tt table was droped :(
exec drop_tt 'www';drop table tt--'
anyone can help?
In short: why are you altering sp? you just need to create a parametrized stored procedure like:
CREATE PROCEDURE uspGetAddress #City nvarchar(30)
AS
SELECT *
FROM AdventureWorks.Person.Address
WHERE City = #City
GO
Just look at this very simple tutorial , you don't need to alter your procedures.
Edit: my approach would be to get rid off the statement EXEC sp_executesql and naming that starts with drop. Just try to simplify your stored procedure execution statement in the body.

Dynamic Datasource in SQL Server Stored Procudure

I have a SQL Server that houses Several Databases. I have a Main Database that holds several tables with entities and ID numbers. Then, each one of those entities has a correlating database (not a table, but database) with all of its information. For example, if the an entity in the MAIN database has an ID number of 1, there would be an SubDatabase1 Database on the same SQL Server.
Essentially, what I am trying to do is create a stored procedure in the MAIN Database, that collects data from the SUB Database, but the SUB database I collect from should be determined based on the ID number passed to the Proc.
I know this is totally incorrect, but I am wondering if someone can shine some light on this for me.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE GetInstallationCount
-- Add the parameters for the stored procedure here
#installId int=0
AS
BEGIN
SET NOCOUNT ON;
//Trying to make the DatabaseName dynamic here!!
select count(*) from dbo.Installation#installId.Names
END
GO
Thanks - J
Read up on how to create dynamic SQL, particularly sp_executesql. This should get you started:
DECLARE #theSql varchar(1000)
DECLARE #installId int
SET #installId = 1
SET #theSql = 'SELECT COUNT(*) FROM dbo.Installation' + CAST(#installId as nvarchar) + '.Names'
EXEC (#theSql)
You have to use dynamic SQL to do that. Table names and database names cannot be resolved at runtime in any other way.
Here is a good introduction to this technique by Scott Mitchell.
As often, the answer to such a question is dynamic SQL:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE GetInstallationCount
-- Add the parameters for the stored procedure here
#installId int=0
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql nvarchar(MAX)
SET #sql = 'select count(*) from dbo.Installation' + Cast(#installId as nvarchar) + '.Names'
EXECUTE dbo.sp_executesql #sql
END
GO
Definately could be done by building up the select string dynamically and executing but it would be nasty.
You could get very flashy and try create synonyms of the fly, use them in the queries and then drop them but I'm not sure it would be worth it.
Use synonyms. For example this sets synonym dbo.MySpecialTable to point to table dbo.SomeTable in database DB_3.
IF object_id(N'SN', N'dbo.MySpecialTable') IS NOT NULL
DROP SYNONYM dbo.MySpecialTable
CREATE SYNONYM dbo.MySpecialTable FOR [DB_3].[dbo].[SomeTable]
With this in place, write all your queries to use synonyms instead of real table names. Synonyms have DB scope, so manage "target switching" at one place, maybe in a stored procedure.