Executing scripts as XML in Azure Synapse Analytics - sql-server

I am not able to execute a script by parsing it as XML as mentioned here. I see that it is not supported in Synapse based on MSDN. Could someone please help me how could I achieve this in SQL DW? I have a table that have all the SQL Statements and I want to execute them by looping through each record in that column.
DDL:
CREATE TABLE [#Temp]
(
JOB_ID INT NOT NULL,
SQL_STMNT NVARCHAR(2000)
);
DML:
INSERT INTO #Temp
SELECT 100, 'SELECT * FROM Table_A WHERE MyDate = #ProcessDate'
UNION
SELECT 103, 'SELECT * FROM Table_B WHERE MyDate = #ProcessDate AND MyCode = ''ABC'''
UNION
SELECT 110, 'SELECT * FROM Table_C WHERE MyDate = #ProcessDate AND MyID = 345'
UNION
SELECT 200, 'SELECT * FROM Table_D WHERE MyDate = #ProcessDate'
UNION
SELECT 230, 'SELECT * FROM Table_E WHERE MyDate = #ProcessDate'

You can use the STRING_AGG function:
DECLARE #sql nvarchar(max) = (
SELECT STRING_AGG(CAST(SQL_STMNT as nvarchar(max)), '; ') WITHIN GROUP (ORDER BY JOB_ID ASC)
FROM #Temp
);
exec(#sql);

Related

Passing table name from a list of tables to a SELECT query

My organisation will soon be receiving a varying number of datasets every month which our Data Services team loads each dataset into their own table i.e. 47 files submitted, 47 tables in the database. Not a pretty approach but it will be improved in time. The year and month of submission is part of the table name. i.e. CMorgNZ322_200701PLD ….. NZ322_200701 being the variable part of the table name; NZ322X is the origin of the data and 200701 being April 2007 (based on financial year)
I don’t want to be a slave to editing a SELECT query just to amend the table name month after month so I want to write a stored procedure that passes the table name from one SELECT query to a 2nd SELECT query
This is my first foray into using LOOPS so I’m wondering what is the best approach and how do I pass the table name into the 2nd SELECT query from the initial SELECT query
DECLARE cur_filestoprocess
DECLARE #vcYrMth VarChar(6)
SET #vcYrMth = ‘200701’
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE ‘CMOrg%’ + #vcYrMth + ‘PLD’;
SELECT COLa,
COLb,
COLc,
COLd,
SUM(COLg) AS ‘Activity’,
SUM(COLk) AS ‘Costs’
INTO RegionABC200701Summary
FROM tablename1
GROUP BY COLa,
COLb,
COLc,
COLd
In advance, thanks for your help…..
Use a dynamic SQL this might not be the most elegant but you should get the idea
DECLARE #tableName NVARCHAR(MAX)
DECLARE #vcYrMth VARCHAR(6)
SET #vcYrMth = '200701'
IF OBJECT_ID('tempdb.dbo.#tmp', 'U') IS NOT NULL
DROP TABLE #tmp;
SELECT TABLE_NAME
INTO #tmp
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'CMOrg%' + #vcYrMth + 'PLD'
DECLARE #rowNum INT
SET #rowNum = 0
DECLARE #length INT
SELECT #length = COUNT(*) FROM #tmp
WHILE (#rowNum < #length)
BEGIN
SELECT #tableName = TABLE_NAME
FROM #tmp
ORDER BY TABLE_NAME OFFSET #rowNum ROWS
FETCH NEXT 1 ROWS ONLY
SELECT #sql = 'SELECT COLa,
COLb,
COLc,
COLd,
SUM(COLg) AS ‘Activity’,
SUM(COLk) AS ‘Costs’
INTO Region'+#tableName+'Summary
FROM tablename1
GROUP BY COLa,
COLb,
COLc,
COLd'
FROM #tmp
--PRINT (#sql)
EXEC (#sql)
SET #rowNum = #rowNum + 1
END
Edited
The above will only work for SQL 2012 and above, use this snippet if using a version below
Replace
SELECT #tableName = TABLE_NAME
FROM #tmp
ORDER BY TABLE_NAME OFFSET #rowNum ROWS
FETCH NEXT 1 ROWS ONLY
With
SELECT #tableName = TABLE_NAME
FROM (
SELECT TABLE_NAME, ROW_NUMBER() OVER (ORDER BY TABLE_NAME) AS RowNumber
FROM #tmp
) a
WHERE RowNumber = #rowNum

Dynamic Pivot SQL in the Common Table Expression (CTE)

I am trying to Pivot a result of a CTE. Due to the privacy laws i cannot put my query and resultset here but the example looks like the below:
WITH CTE1
AS ( select ....)
,CTE2
AS (Select...)
,CTE3
as (Select...)
Below is the result of my CTE2:
and i want the result as
The main issue i am having here is to pivot the resultset with multiple and dynamic Pivot columns between CTE2 and CTE3 as i need to use the Pivot data in CTE3. Is there any solution without changing the CTE's to TempTable? Any help will be appreciated.
I think it's going to be something like this.
Dynamic Pivot:
DECLARE #query VARCHAR(4000)
DECLARE #years VARCHAR(2000)
SELECT #years = STUFF(( SELECT DISTINCT'],[' + [factor_label]
FROM [TEMP_lacp_factors]
ORDER BY '],[' + [factor_label]
FOR XML PATH('')
), 1, 2, '') + ']'
SET #query =
'SELECT * FROM
(
SELECT [date_],[issue_id],[cusip],[Factor_value],[factor_label]
FROM [TEMP_lacp_factors]
)t
PIVOT (MAX([factor_value]) FOR [factor_label]
IN ('+#years+')) AS pvt'
EXECUTE (#query)
Dynamic Pivot and Select Into:
-- Drop the table; you create it dynamically
Drop Table tempTable
--Start creating all objects for Dyanmic Pivot
DECLARE #query VARCHAR(4000)
DECLARE #years VARCHAR(2000)
SELECT #years = STUFF(( SELECT DISTINCT'],[' + [factor_label]
FROM [TEMP_lacp_factors]
ORDER BY '],[' + [factor_label]
FOR XML PATH('')
), 1, 2, '') + ']'
SET #query =
-- Objects that are created above, are put into the table you are about to create below
'SELECT * INTO tempTable FROM (SELECT * FROM
(
SELECT [date_],[issue_id],[cusip],[Factor_value],[factor_label]
FROM [TEMP_lacp_factors]
)t
PIVOT (MAX([factor_value]) FOR [factor_label]
IN ('+#years+')) AS pvt) X'
EXECUTE (#query)
-- Select everything from the dynamically created table ('tempTable') to see results
Select * from tempTable
I'm not 100% sure what you are doing, so it's just a best guess.

Showing "Invalid object name " in sqlServer?

While Executing the Following query it showing the Invalid object name '#temp1'. can any body knows the error occurred due to which reason this is my orginal code i used to fetch code , her differnt tables are formed i need to get the sum of the each row of each table
DECLARE #t TABLE (
id int IDENTITY(1,1),
BranchName nvarchar(max)
)
DECLARE #n int = 0,
#i int = 1,
#BranchName nvarchar(max),
#sql nvarchar(max),
#columns nvarchar(max)
INSERT INTO #t
SELECT DISTINCT BranchName
FROM ALX_Branches
SELECT #n = ##ROWCOUNT
WHILE #n >= #i
BEGIN
SELECT #BranchName = BranchName
FROM #t
WHERE id = #i
SELECT #columns = (
SELECT DISTINCT ','+QUOTENAME([SubInventory])
FROM #MyTempTable
WHERE [BranchName] = #BranchName
FOR XML PATH('')
)
SELECT #sql = N'--
SELECT * into #temp1
FROM (
SELECT [BranchID],
[SubInventory],
[Product],
[Stock]
FROM #MyTempTable
WHERE [BranchName] = ''' +#BranchName +'''
) as t
PIVOT (
MAX([Stock]) FOR [SubInventory] IN ('+STUFF(#columns,1,1,'')+')
) as pvt'
EXEC sp_executesql #sql
select * from #temp1
Firstly, there is no need for creating #temp1 table before.
because you are using "Select * into" that already create table within it.
Suppose type this note as a comment, but I don't have enough reputation score.
The reason of
Invalid object name '#temp1'
is: the variable #sql is NULL because #temp1 is not created yet via "Select * into" clause.
so append selecting from #temp1 within dynamic sql as the following:
SELECT #sql = N'--
SELECT * into #temp1
FROM (
SELECT [BranchID],
[SubInventory],
[Product],
[Stock]
FROM #MyTempTable
WHERE [BranchName] = ''' +#BranchName +'''
) as t
PIVOT (
MAX([Stock]) FOR [SubInventory] IN ('+STUFF(#columns,1,1,'')+')
) as pvt
select * from #temp1 '
EXEC sp_executesql #sql

What is the T-SQL syntax to exclude a duplicate column in the output when joining 2 tables?

I am using SQL Server 2014 and I have the following T-SQL query which joins 2 tables:
SELECT a.*, b.* FROM TEMP a
INNER JOIN Extras b ON b.ResaID = a.ResaID
I would like to pull ALL the columns from TEMP and all the columns from "Extras" with the exception of the ResaID column as it is already included in a.* in the above query. Basically, I want to pull a.* + b.* (excluding b.ResaID).
I know I can write the query in the form:
Select a.*, b.column2, b.column3,...
but since b.* has got around 40 columns, is there a way to write the query in a more simplified way to exclude b.ResaID, rather than specify each of the columns in the "Extras" table?
Unfortunately, there is no such syntax. You could either use asterisks (*) and just ignore the duplicated column in your code, or explicitly list the columns you need.
You should create a view and select the columns you need from that view. Here is a script that will generate that view for you:
DECLARE #table1 nvarchar(20) = 'temp'
DECLARE #table1key nvarchar(20) = 'ResaID'
DECLARE #table2 nvarchar(20) = 'Extras'
DECLARE #table2key nvarchar(20) = 'ResaID'
DECLARE #viewname varchar(20) = 'v_myview'
DECLARE #sql varchar(max) = ''
SELECT #sql += '], a.[' + column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #table1
SELECT #sql += '], b.[' + column_name
FROM
(
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #table2
EXCEPT
SELECT column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = #table1
) x
SELECT
#sql = 'CREATE view ' +#viewname+ ' as SELECT '
+ STUFF(#sql, 1, 3, '') + '] FROM ['
+#table1+ '] a JOIN ['+ #table2
+'] b ON ' + 'a.' + #table1key + '=b.' + #table2key
EXEC(#sql)
You can simply solve this using a dynamic sql query.
DECLARE #V_SQL AS NVARCHAR(2000)='' --variable to store dynamic query
,#V_TAB1 AS NVARCHAR(200)='TEMP' --First Table
,#V_TAB2 AS NVARCHAR(200)='Extras' --Second Table
,#V_CONDITION AS NVARCHAR(2000)='A.ResaID = B.ResaID' --Conditions
SELECT #V_SQL = STUFF(
( SELECT ', '+TCOL_NAME
FROM
( SELECT 'A.'+S.NAME AS TCOL_NAME
FROM SYSCOLUMNS AS S
WHERE OBJECT_NAME(ID) = #V_TAB1
UNION ALL
SELECT 'B.'+S.NAME
FROM SYSCOLUMNS AS S
WHERE OBJECT_NAME(ID) = #V_TAB2
AND S.NAME NOT IN (SELECT S.NAME
FROM SYSCOLUMNS AS S
WHERE OBJECT_NAME(ID) = #V_TAB1)
) D
FOR XML PATH('')
),1,2,'')
EXECUTE ('SELECT '+#V_SQL+'
FROM '+#V_TAB1+' AS A
INNER JOIN '+#V_TAB2+' AS B ON '+#V_CONDITION+' ')

Create table on SQL Server from dynamic pivot results

Is there a way to directly store the results of a dynamic pivot query into a fixed table? As the result is dynamic I can't create the table by specifying the columnnames and methods like "create table MyTable as (pivot select statement)" seem to fail on SQL server ("Incorrect syntax near the keyword 'AS'").
I have tried to format the SQL below to get a SELECT - INTO - FROM structure but failed to do so. Any help is obviously greatly appreciated!
The SQL used for the pivot is (build thanks to this great website!):
declare #pivot varchar(max), #sql varchar(max)
create table pivot_columns (pivot_column varchar(100))
insert into pivot_columns
select distinct DateField from MyTable order by 1
select #pivot=coalesce(#pivot+',','')+'['+pivot_column+']'from pivot_columns
set #sql = 'SELECT * FROM (select DateField, RefCode, SumField from MyTable) p
PIVOT
(sum(SumField) FOR DateField IN ( ' + #pivot + ') )
AS pvl'
drop table pivot_columns
exec (#sql)
Unless I am not following what you are trying to do you should be able to add the INTO mynewTable to your sql that you are going to execute and you should get the new table.
declare #pivot varchar(max), #sql varchar(max)
create table pivot_columns (pivot_column varchar(100))
insert into pivot_columns
select distinct DateField from MyTable order by 1
select #pivot=coalesce(#pivot+',','')+'['+pivot_column+']'from pivot_columns
set #sql = 'SELECT * INTO mynewTable FROM (select DateField, RefCode, SumField from MyTable) p
PIVOT
(sum(SumField) FOR DateField IN ( ' + #pivot + ') )
AS pvl'
drop table pivot_columns
exec (#sql)
I just test creating a new table in the following script and it gives me a new table that is in the DB for use:
create table t
(
[month] int,
[id] nvarchar(20),
[cnt] int
)
insert t values (4,'TOTAL',214)
insert t values (5,'TOTAL',23)
insert t values (6,'TOTAL',23)
insert t values (4,'FUNC',47)
insert t values (5,'FUNC',5)
insert t values (6,'FUNC',5)
insert t values (4,'INDIL',167)
insert t values (5,'INDIL',18)
insert t values (6,'INDIL',18)
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
select #cols = STUFF((SELECT distinct ',' + QUOTENAME(month)
FROM t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT *
INTO tabletest from
(
select month, id, cnt
from t
) x
pivot
(
sum(cnt)
for month in (' + #cols + ')
) p '
execute(#query)
drop table t

Resources