I have a SQL Server table called "tblProducts".
Sometimes I backup this table by making a copy of it with this simple query:
SELECT *
INTO [test01].[dbo].[tblProducts_20141206]
FROM [test01].[dbo].[tblProducts]
Every time when making a backup, the date is included in the table name.
I would like to create a SQL Job that runs this kind of query once every week.
Is it possible to maybe in a stored procedure or declaring a variable to achieve this that allows the backed-up table name to be named like [tblProducts_todaysDate]?
Thanks.
If you are using a SP, you can do something like:
CREATE PROC sp_createATable
#name VARCHAR(20) AS
CREATE TABLE #name
...
do your insert
Or, if you want to, w/o SP:
DECLARE #name varchar(20)
SET #name = 'tblName' + SELECT CONVERT(VARCHAR(8), GETDATE(), 112) AS [YYYYMMDD]
CREATE TABLE #name
...
do your insert
You need Dynamic SQL to create the tables names appended with date.
CREATE PROC usp_createtable( #tablename VARCHAR(20),
#Dbname VARCHAR(20),
#SchemaName VARCHAR(20))
AS
BEGIN
DECLARE #sql NVARCHAR(max)
SET #sql =' SELECT * INTO '+#Dbname+'.'+#SchemaName+'.'+#tablename+'CONVERT(VARCHAR(8), GETDATE(), 112) FROM '+#Dbname+'.'+#SchemaName+'.'+#tablename''
EXEC sp_executesql
#sql
END
Related
A database had has 4 tables that has the same columns EG. SalesJAn, SalesFeb, SalesMarch, SalesApril.
I want to run a query in SQL server or in report builder Where i can change the table name based on a selection which one of 4 tables will be queried . Eg Filter in report builder
Like this
declare #tablename varchar(50)
set #tablename = 'test'
select * from #tablename
You can create a procedure which will do a select for a given table name. This procedure could look like this:
CREATE PROCEDURE EXECUTE_SELECT
#tbl sysname
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQL NVARCHAR(MAX);
SET #SQL = N' SELECT * FROM ' + QUOTENAME(#tbl)
EXECUTE sp_executesql #SQL
END
Then you can execute this procedure for every table name you want. Please see here an example according to your description: db<>fiddle
If this doesn't help you, please point out which exactly you still need to know. Thank you.
We are using SQL Server 2014 Enterprise with many databases. I have to execute query and get reports / data from every database with EXACT SAME Schema and database starts with Cab
When a new company is added in our ERP project a new database is created with exact schema starting with Cab and incremented number is assigned to it like:
Cab1
Cab2
Cab3
Cab5
Cab10
I can get the database names as:
SELECT name
FROM master.sys.databases
where [name] like 'Cab%' order by [name]
I have to create a Stored Procedure to get data from tables of every database.
How to do that using a Stored Procedure as the databases are created dynamically starting with Cab?
You can use EXEC(#Statement) or EXEC SP_EXECUTESQL if you have to pass parameters.
CREATE OR ALTER PROCEDURE dbo.GetDataFromAllDatabases
AS
BEGIN
DECLARE #T TABLE (id INT NOT NULL IDENTITY(1, 1), dbName VARCHAR(256) NOT NULL)
INSERT INTO #T
SELECT NAME FROM MASTER.SYS.DATABASES WHERE [NAME] LIKE 'Cab%' ORDER BY [NAME]
CREATE TABLE #AllData (......)
DECLARE #Id INT, #DbName VARCHAR(128)
SELECT #Id = MIN(Id) FROM #T
WHILE #Id IS NOT NULL
BEGIN
SELECT #DbName = dbName FROM #T WHERE Id = #Id
DECLARE #Statement NVARCHAR(MAX)
SET #Statement = CONCAT(N'INSERT INTO #AllData (...) SELECT .... FROM ', #DbName, '.dbo.[TableName]')
EXEC(#Statement);
--YOU CAN USE BELOW LINE TOO IF YOU NEED TO PASS VARIABLE
--EXEC SP_EXECUTESQL #Statement, '#Value INT', #Value = 128
SET #Id = (SELECT MIN(Id) FROM #T WHERE Id > #Id)
END
END
A quick and easy dynamic SQL solution would be something like this:
DECLARE #Sql nvarchar(max);
SET #Sql = STUFF((
SELECT ' UNION ALL SELECT [ColumnsList], '''+ [name] + ''' As SourceDb FROM '+ QUOTENAME([name]) + '.[SchemaName].[TableName]' + char(10)
FROM master.sys.databases
WHERE [name] LIKE 'Cab%'
FOR XML PATH('')
), 1, 10, '');
--When dealing with dynamic SQL, print is your best friend...
PRINT #Sql
-- Once the #Sql is printed and you can see it looks OK, you can run it.
--EXEC(#Sql)
Notes:
Use quotename to protect against "funny" chars in identifiers names.
Replace [ColumnsList] with the actual list of columns you need.
There's no need for loops of any kind, just a simple stuff + for xml to mimic string_agg (which was only introduced in 2017).
I've thrown in the source database name as a "bonus", if you don't want it that's fine.
The Order by clause in the query that generates the dynamic SQL is meaningless for the final query, so I've removed it.
As I have seen so far, people suggested using dynamic SQL.
For example:
How to pass schema as parameter to a stored procedure in sql server?
How to pass schema name as parameter in stored procedure
However, dynamic SQL has the risk of SQL injection. Hence, I want to know if there are any other safe alternatives?
Basically, this stored procedure that I am creating will be called at runtime. There will be 2 possible schemas to be passed in. And the table name will be passed in as well.
Something like below: (It does not work)
CREATE PROCEDURE [EFM].[usp_readApexTable]
#SCHEMANAME VARCHAR(20) = NULL,
#TABLENAME VARCHAR(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT *
FROM [#SCHEMANAME].[#TABLENAME];
END
GO
This is just an example of READ action. My plan is to create for CRUD, which requires 4 different stored procedures.
You can use QUOTENAME to avoid any SQL injection and build your dynamic query like the following:
CREATE PROCEDURE [EFM].[usp_readApexTable]
#SCHEMANAME VARCHAR(20) = NULL,
#TABLENAME VARCHAR(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #SQL VARCHAR(MAX)=N'SELECT * FROM '
+ QUOTENAME(#SCHEMANAME) + '.' + QUOTENAME(#TABLENAME)
EXEC (#SQL)
END
GO
Note: If you have any plan to add parameters also for your WHERE clause, in that case QUOTENAME will not help much, I suggest to to use sp_executesql by passing appropriate parameters used in WHERE clause.
Still you need to use QUOTENAME for schema and table name as SQL excepts it only as literal, you can't use variable names for table and schema.
For example.
declare #sql nvarchar(max)
set #sql = N'select * from ' + quotename(#SCHEMANAME ) + '.' + quotename(#TABLENAME )
+ ' where (City = #City)'
exec sp_executesql
#sql,
N'#City nvarchar(50)',
#City
You can find more details here
You need to use dynamic sql to do this operation
CREATE PROCEDURE [EFM].[usp_readApexTable]
#SCHEMANAME VARCHAR(20) = NULL,
#TABLENAME VARCHAR(100) = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sqlCommand nvarchar(MAX)
SET #sqlCommand='SELECT * FROM ['+#SCHEMANAME+'].['+#TABLENAME+'];'
--Create Your Temp Table where you can set the records after executing the dynamic query
CREATE TABLE #tmpTbl(
Column1 [datatype]
Column2 [datatype]
.
.
ColumnN
)
INSERT INTO #tmpTbl EXEC sp_executesql #sqlCommand --Copy data to #tmpTbl table
SELECT * FROM #tmpTbl
DROP TABLE #tmpTbl
END
GO
I am trying to write a custom stored procedure to carry out a select into operation. I want to copy a table (or some columns from a table) from one database to another. I am using SQL Server 2012
CREATE Procedure select_into
AS
Begin
#selection varchar(128),
#newtabname varchar(128)
#fromtabname varchar(128)
Select selection,
INTO table1,
FROM table2,
WHERE selection = #selection AND table1 = #newtabname AND table2 =#fromtabname;
go
EXEC select_into, Ecode, relational_db.dbo.work, dbo.Work_Data;
I get an error message indicating a syntax error near the "." in relational_db.dbo.work.
I would appreciate any help in getting this right
You have a missing comma in parameter list and wrong syntax for procedure declaration. It should be::
CREATE Procedure select_into
(
#selection varchar(128),
#newtabname varchar(128),
#fromtabname varchar(128)
)
AS
Begin
BUT, in addition your syntax for an INSERT INTO contains extra commas and you cannot perform dynamic T-SQL that way.
Can I suggest you first learn TSQL's syntax for SQL Server.
Try something like this ...
CREATE Procedure select_into
#selection NVARCHAR(128),
#newtabname NVARCHAR(128),
#fromtabname NVARCHAR(128)
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'Select ' + QUOTENAME(#selection) +
N' INTO ' + QUOTENAME(#newtabname) +
N' FROM ' + QUOTENAME(#fromtabname)
EXECUTE sp_executesql #sql
END
Is this incorrect, can't we pass the table name to a select query dynamically?
This is giving me a error 'Must declare the table variable #TblName'
DECLARE #TblName VARCHAR(30)
SET #TblName = 'User'
SELECT *
FROM #TblName
You need to create a dynamic SQL query, preferably using the QUOTENAME function. You can avoid any issues from malicious input by using QUOTENAME function.
Here is a sample script that illustrates how to query a table by creating a dynamic SQL query by passing in a table name. You can change the table name by value to the variable #tablename.
Create and insert script for sample:
CREATE TABLE sample
(
id INT NOT NULL
);
INSERT INTO sample (id) VALUES
(1),
(2),
(3),
(4),
(5),
(6);
Dynamic SQL script:
DECLARE #execquery AS NVARCHAR(MAX)
DECLARE #tablename AS NVARCHAR(128)
SET #tablename = 'sample'
SET #execquery = N'SELECT * FROM ' + QUOTENAME(#tablename)
EXECUTE sp_executesql #execquery
Demo:
Click here to view the demo in SQL Fiddle.
Suggested read:
The Curse and Blessings of Dynamic SQL
you have to use dynamic sql execution
wrap your statement in #selectstr
use exec sp_executesql #selectstr
You can do this thing by using dynamic query, Check below
DECLARE #TblName VARCHAR(30)
DECLARE #vQuery NVARCHAR(100)
SET #TblName = 'User'
SET #vQuery = 'SELECT * FROM ' + #TblName
EXECUTE sp_executesql #vQuery