Ok I don't know much about stored procedures, but does anyone know how I could write this as an SP. I think it's kinda getting there but not quite. basically what would I need to paste into my query to create it!:)
CREATE PROCEDURE sp_executesql
as
DECLARE
#cols AS NVARCHAR(MAX),
#y AS INT,
#sql AS NVARCHAR(MAX);
-- Construct the column list for the IN clause
SET #cols = STUFF(
(SELECT N',' + QUOTENAME(w) AS [text()]
FROM (SELECT DISTINCT WeekNo AS W FROM dbo.Items) AS W
ORDER BY W
FOR XML PATH('')),
1, 1, N'');
-- Construct the full T-SQL statement
-- and execute dynamically
SET #sql = N'SELECT *
FROM (SELECT ItemNo, WeekNo, Value
FROM dbo.Items) AS I
PIVOT(SUM(Value) FOR WeekNo IN(' + #cols + N')) AS P;';
EXEC sp_executesql #sql;
GO
Assuming the query statement is correct and you need just a SP structure it will be like this:
CREATE PROCEDURE SP_NAME
#variable1 type [input/output]
as
begin
--query
end
//to execute SP
EXEC SP_NAME 'valueForVariable1'
hope this helps
Got it. Just don't name provedure sp_executesql, name it get_items or something else.
new procedure:
CREATE PROCEDURE get_items
as
declare #cols AS NVARCHAR(MAX),
#y AS INT,
#sql AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT N',' + QUOTENAME(w) AS [text()]
FROM (SELECT DISTINCT week_no AS W FROM weekly_items) AS W
ORDER BY W
FOR XML PATH('')),1, 1, N'');
SET #sql = N'SELECT *
FROM (SELECT item_no, week_no, totval
FROM weekly_items) AS I
PIVOT(SUM(totval) FOR week_no IN(' + #cols + N')) AS P;';
EXEC sp_executesql #sql
GO
Related
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
Can you tell me how to insert executed variable #name in my table?
I had some coding and this is what i managed to do but I do not know whats next:
DECLARE #Name nvarchar(200);
DECLARE #dbcatalog nvarchar(128);
declare #sql nvarchar(4000)
select #name = N' select ID from ' + #DbCatalog + '.dbo.Table2 ';
SET #sql = 'insert into Table2(Name) values (#name)'
exec Sp_executeSQL #sql
Are you trying to copy ID values from one table into another? If so, then:
INSERT INTO Table2 (Name)
EXEC(#Name)
SELECT TOP 10
*
FROM
(SELECT
COLUMN_NAME, TABLE_NAME
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME LIKE '%MAIL%')
I am trying to get the top 10 rows from each of the tables within my search. Any ideas? SQL Server 2008 R2
While nscheaffer's answer is valid, I feel obligated to tell you that you can get the exact same functionality without using a cursor, and also while using a query which might be a bit easier to implement.
Just concatenate all of the possible queries together based off the system tables and then execute them simultaneously, like this:
DECLARE #SQL NVARCHAR(MAX)
;
SELECT #SQL =
(
SELECT 'SELECT TOP 10 * FROM ' + OBJECT_NAME(C.Object_ID) + ';' + CHAR(10)
FROM sys.Columns C
INNER JOIN sys.Tables T
ON C.Object_ID = T.Object_ID
AND T.is_ms_shipped = 0
WHERE C.Name LIKE '%Mail%'
GROUP BY C.Object_ID
ORDER BY C.Object_ID
FOR XML PATH('')
)
;
EXEC sp_ExecuteSQL #SQL
;
If you want to check the SQL before it runs, just comment out the EXEC command and replace it with a SELECT, like this:
SELECT #SQL;
--EXEC sp_ExecuteSQL #SQL
;
I would use a cursor to create dynamic SQL and then execute that SQL. Does this work for you?
DECLARE #SQL NVARCHAR (4000) = ''
DECLARE #Table_Name NVARCHAR(50)
DECLARE TableCursor CURSOR FAST_FORWARD READ_ONLY FOR
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%MAIL%'
OPEN TableCursor
FETCH NEXT FROM TableCursor INTO #Table_Name
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = #SQL + '
SELECT TOP 10 * FROM ' + #Table_Name + '
GO
'
FETCH NEXT FROM TableCursor INTO #Table_Name
END
CLOSE TableCursor
DEALLOCATE TableCursor
EXECUTE sp_executeSQL #SQL
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);
I have a query that is dynamically fetching the stored proc names from all the databases.
Now I want to execute the stored procs and store the result in a temptable or table variable.
How to do that. Here is my SP so far
Declare #GetDBNames sysname
Declare #DynSql nvarchar(max)
Declare DBNames cursor for
Select '['+name+']' from master.dbo.sysdatabases
open DBNames
FETCH NEXT FROM DBNames into #GetDBNames
WHILE ##FETCH_STATUS=0
BEGIN
SET #DynSql = '
Select Specific_Catalog as Database_Name, Routine_Name as ''Stored Procedure Name''
From '+ #GetDBNames+'.Information_Schema.Routines '
EXEC (#DynSql)
FETCH NEXT FROM DBNames into #GetDBNames
END
Close DBNames
Deallocate DBNames
Please help.
Thanks in advance
Here's my soluton. Cursors are evil :)
Declare #DynSql nvarchar(max)
declare #result table ([Database_Name] nvarchar(128), [Stored Procedure Name] sysname)
SET #DynSql = ''
select #DynSql = #DynSql + '
Select SPECIFIC_CATALOG COLLATE DATABASE_DEFAULT as Database_Name, ROUTINE_NAME COLLATE DATABASE_DEFAULT as [Stored Procedure Name]
From ' + NAME + '.INFORMATION_SCHEMA.ROUTINES' + CHAR(13) + 'union all' + CHAR(13)
from master.dbo.sysdatabases
--remove last "union all"
SET #DynSql = left(#DynSql, LEN(#DynSql) - 10)
insert #result
exec sp_executesql #DynSql
select * from #result
INSERT [TableName] EXEC (#DynSql)
Note that if you introduce data you may want to use sp_ExecuteSQL, and you probably want to use [/] object-name escaping.