SQL - insert into QUOTENAME(#DatabaseName) - tsql

DECLARE #DatabaseName varchar(30), #Article varchar(16), #PartnerID int
set #DatabaseName = 'DEMO'
set #Article = 'Article1'
set #PartnerID = 1
INSERT INTO QUOTENAME(#DatabaseName) + '.dbo.move(Article, Partner, Note)'
select #Article, #PartnerID, 'Note'
I have this and error is:
Msg 102, Level 15, State 1, Line 7
Incorrect syntax near '+'.
I try:
DECLARE #SQL nvarchar(max)
DECLARE #DatabaseName varchar(30), #Article varchar(16), #PartnerID int
set #DatabaseName = 'Demo'
set #Article = 'Article1'
set #PartnerID = 1
set #SQL = N'INSERT INTO '+ QUOTENAME(#DatabaseName) + N'.dbo.move(Article, Partner, Note)'
+ N'select ' + #Article + N', ' + #PartnerID + N', '''Note''' '
exec #SQL
But I get this error:
Msg 102, Level 15, State 1, Line 9
Incorrect syntax near 'Note'.

If you are going to use dynamic SQL (which should be avoided if you have alternatives), it's still a good idea to use sp_executesql and parameters, and using REPLACE to construct statements rather than concatenation saves a lot of headaches debugging the proper escaping. In your example:
SET #SQL = REPLACE(
'INSERT INTO $database.dbo.move(Article, Partner, Note)
VALUES (#Article, #Partner, ''Note'')',
'$database', QUOTENAME(#DatabaseName)
);
PRINT #SQL; -- check what we've produced
EXECUTE sp_executesql
#stmt = #sql,
#params = N'#Article VARCHAR(16), #Partner INT',
#Article = #Article, #Partner = #PartnerID
;

Related

result of sp_executesql in a variable

How can I get the output of the below query in a variable without temp table?
DECLARE #Q1 NVARCHAR(300)
DECLARE #Q2 NVARCHAR(300)
DECLARE #Q3 NVARCHAR(300)
SET #Q1 = 'SELECT ' +' ' + #formfieldpath
SET #Q2 = 'FROM [TestDatabase].[details] WHERE id ' + '=''' + CAST(#id AS VARCHAR(10)) + '''';
SET #Q3 = #Q1 +' '+ #Q2
PRINT #Q3
EXEC sp_executesql #Q3
Tried 'How to get sp_executesql result into a variable?' and not able to get the results.
Assuming that you get a singleton value from your dynamic statement:
DECLARE #ID int, --Is set somewhere
#YourVariable nvarchar(30), --Use an appropriate data type
#formfieldpath sysname; --Is set somewhere
DECLARE #SQL nvarchar(MAX);
--I assume that the name [TestDatabase].[details] is wrong, as [TestDatabase] would be the name of the schema, not the database,
--and I ASSUME you haven't foolishy created a schema called "TestDatabase"
SET #SQL = N'SELECT #YourVariable = ' + QUOTENAME(#formfieldpath) + N' FROM dbo.Details WHERE id = #id';
--Use the correct datatype for #YourVariable
EXEC sys.sp_executesql #SQL, N'#id int, #YourVariable nvarchar(30) OUTPUT', #id, #YourVariable OUTPUT;
Never inject unsanitised values into a dynamic SQL statement. SQL injection is a huge problem that should have stopped existing over a decade ago. Dos and Don'ts of Dynamic SQL

Using a Cursor to Create Triggers for all tables in a database

I am using SQL Server 2005
I am trying to create a trigger for each table contained within a database and keep getting an error which I do not understand and can not fix
If anyone has an idea of why I am getting this error or how I can resolve it that would be brilliant.
DECLARE #TableName AS VARCHAR(100)
DECLARE #audit_action as varchar(100)
DECLARE RDS_cusor CURSOR FOR
SELECT TABLE_NAME FROM [RawDataStorage].INFORMATION_SCHEMA.Tables WHERE TABLE_NAME LIKE 't_%' AND TABLE_NAME NOT LIKE 'tbl_%'
OPEN RDS_cursor
FETCH NEXT FROM RDS_cursor INTO #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
CREATE TRIGGER dbo.After_Insert_Trig
ON [dbo].[t_Agent]
AFTER INSERT,DELETE,UPDATE
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO RawDataStorage_Audit
(TableName,Audit_Action,Audit_Timestamp)
VALUES('TableName','audit_action',getdate());
END
GO
FETCH NEXT FROM RDS_cursor INTO #TableName
END
CLOSE RDS_cursor
DEALLOCATE RDS_cursor
This is the error I am getting:
Msg 156, Level 15, State 1, Line 15
Incorrect syntax near the keyword 'TRIGGER'.
Msg 102, Level 15, State 1, Line 26
Incorrect syntax near 'END'.
Msg 137, Level 15, State 2, Line 2
Must declare the scalar variable "#TableName".
any help would be greatly appreachiated
I managed to put this together, its a dynamic query that builds the sql to create the triggers using a cursor to grab the table names from the sysobjects.
CREATE TABLE [dbo].[RawDataStorage_Audit](
ID INT IDENTITY(1,1) NOT NULL,
TableName VARCHAR(50) NULL,
audDateLastChanged DATETIME null
)
Declare #TableName nvarchar(100)
Declare #SQL nvarchar(1000)
declare tables_cursor CURSOR FOR
select [name] from sysobjects
where xtype = 'U'
and [name] not like 'sys%'
order by [name]
Open tables_cursor
fetch next from tables_cursor into #TableName
WHILE ##FETCH_STATUS = 0
Begin
--create trigger for insert on each table
print #SQL
set #SQL = 'create trigger trg_u_'+#TableName+'_Inserted '
set #SQL = #SQL + ' on '+#TableName
set #SQL = #SQL + ' for insert '
set #SQL = #SQL + ' as '
set #SQL = #SQL + ' begin '
set #SQL = #SQL + ' insert into [dbo].[RawDataStorage_Audit] '
set #SQL = #SQL + ' select ''' + #TableName +''', getdate()'
set #SQL = #SQL + ' from inserted'
set #SQL = #SQL + ' end'
exec (#SQL)
print #SQL
fetch next from tables_cursor into #TableName
end
CLOSE tables_cursor
DEALLOCATE tables_cursor

How do i can resolve this promblem?

I have an table include 1 column ID and 12 columns month (Month01 to Month12). If i have an parameter #month=9, how can i compare to get column Month01 to Month09 without Month10, Month11, Month12. Please help me!
Simo's answer is more elegant, but below is an alternative "basic" way to do this:
DECLARE #month INT
SET #month = 9
IF #Month = 1
BEGIN
SELECT Id, Month01
FROM MonthlyData
END
IF #Month = 2
BEGIN
SELECT Id, Month01, Month02
FROM MonthlyData
END
-- Repeat for months 3-9
IF #Month = 9
BEGIN
SELECT Id, Month01, Month02, Month03, Month04,
Month05, Month06, Month07, Month08, Month09
FROM MonthlyData
END
-- Repeat for months 10-12
See my SQL Fiddle.
declare #str varchar(1000)
SELECT #str= coalesce(#str + ', ', '') + a.name
FROM (
Select name from sys.columns
where object_id = OBJECT_ID('table_months')
and isnumeric(right(name,2))= 1 and name like 'month%'
and cast(right(name,2) as int) < '03') a
-- Instead of '03' you use a variable and assign required moths number
declare #sql nvarchar(100)
set #sql = 'select ID, '+ #str+' from table_months'
exec sp_executesql #sql
you may try this out also :)
DECLARE #month int = 9
DECLARE #Sql nvarchar(100) =''
DECLARE #pos int = 1
WHILE(#pos <= #month)
BEGIN
SET #Sql = #Sql + (',month' + right('00'+ rtrim(#pos), 2))
SET #pos = #pos + 1
END
SET #Sql= 'SELECT ID ' +#Sql + ' FROM table'
EXEC sp_executesql #Sql
DECLARE #month int
DECLARE #tableName nvarchar(128)
SET #month = 9;
SET #tableName = 'months' -- YOUR TABLE's NAME
DECLARE #query nvarchar(2048)
SET #query =
'SELECT id, ' + STUFF((SELECT DISTINCT ', ' + name
FROM sys.columns WHERE name LIKE'Month%'
AND object_id = OBJECT_ID(#tableName)
AND CONVERT(INT, RIGHT(name, 2)) <= #month
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'),1,1,'')
+ ' FROM ' + #tableName;
EXEC(#query)

Altering Multiple Tables at once

I'm trying to alter multiple SQL Server 2008 R2 tables at one time.
This is my code:
use DatabaseName
go
Declare #SchemaUsed varchar(20) = 'dbo'
create table #Tables
(
TableName varchar(100), Processed int
)
insert into #Tables
select top 1 table_name, 0
from INFORMATION_SCHEMA.TABLES
where TABLE_SCHEMA = #SchemaUsed
and table_type = 'Base Table'
and (TABLE_NAME like 'PM%' )
ORDER BY TABLE_NAME
DECLARE #TableName varchar(max)
DECLARE #SQL varchar(max)
WHILE EXISTS (select top 1 'x' from #Tables where Processed = 0)
BEGIN
SET #TableName = (select top 1 TableName from #Tables where Processed = 0)
Set #SQL = 'ALTER TABLE ' + #SchemaUsed + '.' + #TableName + ' ADD [identityID] bigint IDENTITY(1, 1) NOT NULL '
-- Set #SQL = '''' + #SQL + ''''
Print #SQL
EXEC #SQL;
update #Tables
set Processed = 1
where TableName = #TableName
END
drop table #Tables
I can't get this to work to save my life and get the following error:
Lookup Error - SQL Server Database Error: The name 'ALTER TABLE
dbo.PM1GTVLV ADD [identityID] bigint IDENTITY(1, 1) NOT NULL ' is not
a valid identifier.
I've also tried multiple string variations and using sp_executesql as well.
Can someone point out where I've gone wrong?
Try
DECLARE #SQL NVARCHAR(MAX);
EXEC sp_executesql #SQL;
Instead of EXEC #sql.
As an aside, this is a much more usable version of the same code IMHO:
DECLARE #SchemaUsed VARCHAR(20) = 'dbo';
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql += CHAR(13) + CHAR(10) + N'ALTER TABLE '
+ QUOTENAME(#SchemaUsed) + '.'
+ QUOTENAME(name) + ' ADD [identityID]
BIGINT IDENTITY(1,1) NOT NULL;'
FROM sys.tables
WHERE SCHEMA_NAME([schema_id]) = #SchemaUsed
AND name LIKE 'PM%';
PRINT #sql;
--EXEC sp_executesql #sql;
Or even better:
DECLARE #SchemaUsed VARCHAR(20) = 'dbo';
DECLARE #sql NVARCHAR(MAX) = N'';
SELECT #sql += CHAR(13) + CHAR(10) + N'ALTER TABLE '
+ QUOTENAME(#SchemaUsed) + '.'
+ QUOTENAME(name) + ' ADD [identityID]
BIGINT IDENTITY(1,1) NOT NULL;'
FROM sys.tables AS t
WHERE SCHEMA_NAME([schema_id]) = #SchemaUsed
AND name LIKE 'PM%'
AND NOT EXISTS (SELECT 1 FROM sys.columns AS c
WHERE [object_id] = t.[object_id]
AND c.is_identity = 1);
PRINT #sql;
--EXEC sp_executesql #sql;
To execute a character string, EXEC requires parenthesis around the string (or character variable) as shown in the BOL syntax:
EXEC (#SQL);

Adding GUID parameter to a sql string

I am having complications adding a guid type to a sql string and getting the query to go. I have to write the sql this because I need to pass the name database as a parameter.
The following code is what I'm trying to do but it doesnt work. No matter what I do it doesn't read the GUID correctly. It gives me the following error when executing the stored proc. Probably because guid has "-" in them
Incorrect syntax near '-'.
Here's the code:
ALTER PROCEDURE [dbo].[templatesAndBaskets_Select]
#guid uniqueidentifier,
#DatabaseName varchar(50)
AS
BEGIN
Declare #sql varchar(max)
Set #sql=
'select soldtoid
from ' + #DatabaseName + '.templatesAndBaskets' +
' where ordergroupid = ' + CONVERT(varchar(max),#guid)
print #sql
EXECUTE SP_EXECUTESQL #sql
END
You probably just simply need to put single quotes around the GUID :
SET #sql =
N'SELECT soldtoid FROM ' + #DatabaseName + N'.templatesAndBaskets' +
N' WHERE ordergroupid = ''' + CONVERT(nvarchar(max), #guid) + N''''
That should result in a SQL statement something like this:
SELECT soldtoid FROM database.templatesAndBaskets
WHERE ordergroupid = '5E736CE7-5527-40ED-8499-2CA93FC7BC9C'
which is valid - yours without the single quotes around the GUID isn't valid...
Update: you also need to change your #sql variable to NVARCHAR for sp_Executesql - try this:
ALTER PROCEDURE [dbo].[templatesAndBaskets_Select]
#guid uniqueidentifier,
#DatabaseName NVARCHAR(50)
AS
BEGIN
DECLARE #sql NVARCHAR(MAX)
SET #sql =
N'SELECT soldtoid FROM ' + #DatabaseName + N'.templatesAndBaskets' +
N' WHERE ordergroupid = ''' + CONVERT(nvarchar(max), #guid) + N''''
PRINT #sql
EXECUTE sp_ExecuteSQL #sql
END
Does that work??
Put the #guid between '
ALTER PROCEDURE [dbo].[templatesAndBaskets_Select]
#guid uniqueidentifier,
#DatabaseName varchar(50)
AS
BEGIN
Declare #sql varchar(max)
Set #sql=
"select soldtoid from " + #DatabaseName + ".templatesAndBaskets" +
" where ordergroupid = '" + CONVERT(varchar(max),#guid)+"'"
print #sql
EXECUTE SP_EXECUTESQL #sql
END