SQL output of dynamic queries should be in csv - sql

Referring to the code in one of the links found in the internet - that executes sql command stored in DB column
I was trying to get similar output in the form of csv - like query and data along with headers in one result.
Like if we have this data in sql server 2014
CREATE TABLE Table1 (empid INT,
name VARCHAR(1000),
sal INT,
DOB DATETIME,
OrgID INT);
CREATE TABLE Table2 (OrgID INT,
Orgname VARCHAR(1000));
CREATE TABLE Table3 (dummy INT);
INSERT INTO Table1
VALUES (100, 'tst', '10000', '1990-11-20', 1);
INSERT INTO Table1
VALUES (101, 'tst', '10000', '1990-11-20', 1);
INSERT INTO Table1
VALUES (102, 'tst', '10000', '1990-11-20', 2);
INSERT INTO Table2
VALUES (1, 'org1');
INSERT INTO Table2
VALUES (2, 'org2');
CREATE TABLE #List (Command VARCHAR(MAX),
OrderBy INT IDENTITY(1, 1));
INSERT INTO #List
VALUES ('SELECT * FROM Table1'),
('SELECT * FROM Table2'),
('SELECT * FROM Table3');
DECLARE #sqlcmd VARCHAR(MAX);
SELECT #sqlcmd = STUFF(
(SELECT ';' + CHAR(10) + Command + CHAR(10)FROM #List ORDER BY [OrderBy] FOR XML PATH('')), 1, 1, '');
EXEC (#sqlcmd);
Now when i execute the sql's in #List, the output should result with comma seperated.
As they are no records in table3, it should not output in final result.
Am expected the the result all in one column seperated by comma - screenshot attached.
OUTPUT
SELECT FROM Table1, empid,name,sal,DOB,OrgID
SELECT FROM Table1, 100,tst,10000,1990-11-20 00:00:00.000,1
SELECT FROM Table1, 101,tst,10000,1990-11-20 00:00:00.000,1
SELECT FROM Table1, 102,tst,10000,1990-11-20 00:00:00.000,2
select from Table2,OrgID, Orgname
select from Table2,1,org1
select * from Table2,2,org2

Related

SQL Server : procedure tables cannot insert value null

I want to add 100 storages in a table.
This is my procedure:
CREATE PROCEDURE [add100*sTORAGE]
AS
DECLARE #i int, #start DATETIME, #end DATETIME
SET #start = GETDATE()
SET #i = 1
WHILE #i < 101
BEGIN
INSERT INTO Storage(storage_name)
VALUES (CONCAT('Nume', CONVERT(nvarchar, #i)))
SET #i = #i +1
END
SET #end = GETDATE()
DECLARE #testID INT = (SELECT TOP 1 (TestRunID)
FROM TestRuns
ORDER BY TestRunID DESC)
DECLARE #tableID INT = (SELECT tableID
FROM Tables
WHERE Name = 'Storage')
INSERT INTO TestRunTables (TestRunID, TableID, StartAt, EndAt)
VALUES (#testID, #tableID, #start, #end)
GO
I get an error after its execution:
Msg 515, Level 16, State 2, Procedure add100*sTORAGE, Line 13
Cannot insert the value NULL into column 'TestRunID', table 'OnlineShop.dbo.TestRunTables'; column does not allow nulls. INSERT fails.
When I look in the table, it has been created 99 columns.
I have some empty tables in a relation and this are the inserts of it (maybe here is the cause):
--INSERTS--
-- insert views into "Views"
INSERT INTO Views(Name) VALUES ('View1')
INSERT INTO Views(Name) VALUES ('View2')
INSERT INTO Views(Name) VALUES ('View3')
select * from views
delete from views where ViewID>1
-- insert into "Tests"
INSERT INTO Tests(Name) VALUES ('[add100*Storage-runView1-del100*Storage]')
INSERT INTO Tests(Name) VALUES ('[add100*Product-runView2-del100*Product]')
INSERT INTO Tests(Name) VALUES ('[add100*OrderProduct-runView3- del100*OrderProduct]')
SELECT * FROM Tests
--insert into tables
INSERT INTO Tables(Name) VALUES ('Table1')
INSERT INTO Tables(Name) VALUES ('Table2')
INSERT INTO Tables(Name) VALUES ('Table3')
SELECT * from Tables
-- insert into "testTable"
INSERT INTO TestTables(TestID, TableID, NoOfRows, Position) VALUES (1,1,100,1)
INSERT INTO TestTables(TestID, TableID, NoOfRows, Position) VALUES (3,2,100,1)
INSERT INTO TestTables(TestID, TableID, NoOfRows, Position) VALUES (2,3,100,1)
SELECT * FROM TestTables
-- insert into "testViews"
INSERT INTO TestViews(TestID,ViewID) VALUES (1,1)
INSERT INTO TestViews(TestID,ViewID) VALUES (3,2)
INSERT INTO TestViews(TestID,ViewID) VALUES (2,3)
SELECT * FROM TestViews
What's wrong? Thank you.
The error tells you everything--table TestRunTables has column "TestRunID" which requires that field to have a value. You either need to be sure to insert a value into that field, or alter the column so that it will use a default value when you don't specify it.
This line:
DECLARE #testID INT = (SELECT TOP 1 (TestRunID) FROM TestRuns ORDER BY TestRunID DESC)
will set #testID to null if no records are returned from TestRuns or if the first TestRunID is null. This is probably what you need to fix.

How to get The QueryString Without EXEC and Print Function

I have other table #table3 where the #qur will be stored and using that #qur i want to retrieve the data.
so it is possible to get data without set all query in other variable and execute this query directly.
this string of #qur not fixed it will different for different person.
and yes i use sql server 2010
CREATE TABLE #Table1
([Name] varchar(5), [DateVal] date, [TimeVal] time, [Item] varchar(5))
;
INSERT INTO #Table1
([Name], [DateVal], [TimeVal], [Item])
VALUES
('Lisa', '2015-04-21', '10:20:06', 'Item1'),
('John', '2015-04-21', '10:25:30', 'Item2'),
('Peter', '2015-03-18', '13:35:32', 'Item3'),
('Ralf', '2015-04-03', '09:26:52', 'Item4')
;
CREATE TABLE #Table2
([ID] int, [Name] varchar(5))
;
INSERT INTO #Table2
([ID],[Name])
VALUES
(1,'Lisa' ),
(2,'John' ),
(3,'Peter'),
(4,'Ralf')
;
DECLARE #qur VARCHAR(2000)='([Item] in (''Item1,Item2'')) and [Name]=''Lisa'') '
SELECT DateVal FROM #Table1
WHERE [Name] in (SELECT [Name] FROM #Table2)
AND #qur
Maybe You can use the query bellow in SQLCMD mode:
:setvar qur "and ([Item] in ('Item1','Item2')) and [Name]='Lisa' "
SELECT DateVal FROM #Table1
WHERE [Name] in (SELECT [Name] FROM #Table2)
$(qur)

Iterating through a SQL Server 2008 R2 table variable and concatenate values

I have a table variable #Holding two columns: an id (not unique) and a message:
id message
---- -------
2 give
2 me
2 help
3 Need
3 help
1 help!
The result should be
2 give me help
3 Need help
1 help!
This it very much simplified, but shows that there are id which may exist more than once, and some kind of text which should be concatenated into a string.
I cannot manage it to loop through this table variable (but not through a table too!).
I tried a cursor (which I did not understand correctly) but it failed of course.
The number of records are not that much, not even 100 in that table variable.
Thanks yr. help
Michael
Original question
No CURSOR, WHILE loop, or User-Defined Function needed.
Just need to be creative with FOR XML and PATH.
[Note: This solution only works on SQL 2005 and later. Original question didn't specify the version in use.]
CREATE TABLE #YourTable ([ID] INT, [Name] CHAR(1), [Value] INT)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'A',4)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'B',8)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (2,'C',9)
SELECT
[ID],
STUFF((
SELECT ', ' + [Name] + ':' + CAST([Value] AS VARCHAR(MAX))
FROM #YourTable
WHERE (ID = Results.ID)
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS NameValues
FROM #YourTable Results
GROUP BY ID
DROP TABLE #YourTable
This should work if you are using SQL Server.
select T1.id,
stuff((select ' '+T2.[message]
from #A as T2
where T1.id = T2.id
for xml path(''), type).value('.', 'varchar(max)'), 1, 1, '') as [message]
from #A as T1
group by T1.id
Pretty the same, just less letters in the code:
DECLARE #t AS TABLE ( id INT, msg VARCHAR(100) );
INSERT INTO #t
VALUES ( 2, 'give' );
INSERT INTO #t
VALUES ( 2, 'me' );
INSERT INTO #t
VALUES ( 2, 'help' );
INSERT INTO #t
VALUES ( 3, 'Need' );
INSERT INTO #t
VALUES ( 3, 'help' );
INSERT INTO #t
VALUES ( 1, 'help!' );
SELECT DISTINCT
id ,
(
SELECT ST1.msg + ' '
FROM #t ST1
WHERE ST1.id = ST2.id
FOR XML PATH('')
) t
FROM
#t ST2;

Can a Pivot table be used with a unknown number of columns?

If I have a team table with a unknown amount of members, is there a way to make the pivot query dynamic?
create table #t (
team varchar (20), member varchar (20)
)
insert into #t values ('ERP', 'Jack')
insert into #t values ('ERP', 'John')
insert into #t values ('ERP', 'Mary')
insert into #t values ('ERP', 'Tim')
insert into #t values ('CRM', 'Robert')
insert into #t values ('CRM', 'Diana')
select * from #t
select team, [1] as teamMember1, /* 1st select */
[2] as teamMember2, [3] as teamMember3
from
(select team , member, row_number () /* 3rd select */
over (partition by team order by team) as rownum
from #t) a
pivot (max(member) for rownum in ([1], [2], [3])) as pvt
drop table #t
Why yes, yes there is. Here's a script I cooked up years ago for a similar problem that was ultimately solved by giving the user Excel and washing my hands of it. I apologize it's not configured with your example data, but hopefully it's easy to follow.
Hope that helps,
John
--------------START QUERY--------------
-- Example Table
CREATE TABLE #glbTestTable
(
ProviderID INT,
Total INT,
PaymentDate SMALLDATETIME
)
--So the dates insert properly
SET DATEFORMAT dmy
-- Populate Example Table
INSERT INTO #glbTestTable VALUES (232, 12200, '12/01/09')
INSERT INTO #glbTestTable VALUES (456, 10200, '12/01/09')
INSERT INTO #glbTestTable VALUES (563, 11899, '02/03/09')
INSERT INTO #glbTestTable VALUES (221, 5239, '13/04/09')
INSERT INTO #glbTestTable VALUES (987, 7899, '02/03/09')
INSERT INTO #glbTestTable VALUES (1, 1234, '02/08/09')
INSERT INTO #glbTestTable VALUES (2, 4321, '02/07/09')
INSERT INTO #glbTestTable VALUES (3, 5555, '02/06/09')
-- Raw Output
SELECT *
FROM #glbTestTable
-- Build Query for Pivot --
DECLARE #pvtColumns VARCHAR(MAX)
SET #pvtColumns = ''
-- Grab up to the first 1023 "Columns" that we want to use in Pivot Table.
-- Tables can only have 1024 columns at a maximum
SELECT TOP 1023 #pvtColumns = #pvtColumns + '[' + CONVERT(VARCHAR, PaymentDate, 103) + '], '
FROM (SELECT DISTINCT PaymentDate FROM #glbTestTable) t_distFP
-- Create PivotTable Query
DECLARE #myQuery VARCHAR(MAX)
SET #myQuery = '
SELECT ProviderID, ' + LEFT(#pvtColumns, LEN(#pvtColumns) - 1) + '
FROM (SELECT ProviderID, PaymentDate, Total
FROM #glbTestTable) AS SourceTable
PIVOT
(
SUM(Total)
FOR PaymentDate IN (' + LEFT(#pvtColumns, LEN(#pvtColumns) - 1) + ')
) AS PivotTable'
-- Run the Pivot Query
EXEC(#myQuery)
-- Cleanup
DROP TABLE #glbTestTable
---------------END QUERY---------------

Formulation of insert into keyword in SQL Server

I want to insert some values to the table, there is an order such as 1,2,3....n
Insert Into table_name VALUES ( '1', 'A' )
Insert Into table_name VALUES ( '2', 'AA' )
Insert Into table_name VALUES ( '3', 'AAC' )
Insert Into table_name VALUES ( '.', '....' )
Insert Into table_name VALUES ( '.', '....' )
Insert Into table_name VALUES ( 'n', '....' )
How can I formulate this INSERT statement?
If you want to insert a series of rows - sure, you can use a loop - but how do you know what other values (other than the index) to get??
DECLARE #index INT
SET #index = 0
WHILE #index < 10
BEGIN
INSERT INTO dbo.table_name(Index)
VALUES( CAST(#index AS VARCHAR(50)) ) -- or whatever type you need....
SET #index = #index + 1
END
The usual way to do this is to select the values to insert from somewhere else:
INSERT INTO company1.new_customers (id, name, address)
SELECT
NULL -- this will trigger the DB to auto-generate the new id's
,name
,address
FROM company2.old_customers
If you have to use a loop in SQL you're doing it wrong.
SQL works with sets.