Exporting stored procedure result to excel - excel

Similar Question may have been asked on this forum regarding exporting stored procedure result to excel file,I've tried few attempts to this but the file does not export to the folder that I expect,Your help is appreciated
Stored Procedure that I created
/****** Object: StoredProcedure [dbo].[Copy_DataDump_SpecificQuery] Script Date: 10/28/2014 15:59:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROC [dbo].[Copy_DataDump_SpecificQuery]
#SQLScript VARCHAR(MAX)
,#OutPut_Number INT OUTPUT
,#Output_FIleName VARCHAR(MAX) OUTPUT
AS
SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
BEGIN
BEGIN TRY
DECLARE #server Varchar (100)
SET #server = 'MyServerName'
DECLARE #FileName VARCHAR(255)
DECLARE #Date VARCHAR(12)
SELECT #Date = CONVERT(VARCHAR(10),GETDATE(),120)
SET #Output_FIleName = CAST(NEWID() AS VARCHAR(MAX))+ '.xls'
DECLARE #FilePath VARCHAR (4000)
SET #FilePath = '\\ComputerName\Users\MyUserName\Downloads\Exel_File' + #Output_FIleName ;
IF OBJECT_ID('tempDB..##temp_Query', 'U') IS NOT NULL
DROP TABLE ##temp_Query;
----------------------------------------------------------------------------------------------
DECLARE #Query AS VARCHAR(MAX)
DECLARE #FROM_Start INT
SELECT #FROM_Start = CHARINDEX(' FROM ',#SQLScript)
SELECT #Query = SUBSTRING(#SQLScript,0,#FROM_Start) + ' INTO ##temp_Query FROM ' + SUBSTRING(#SQLScript,#FROM_Start+6,LEN(#SQLScript))
PRINT (#Query)
Exec(#Query)
------------------------------------------------------------------------------------------------------------------
DECLARE #dbName VARCHAR (100)
SET #dbName = 'master'
DECLARE #sql VARCHAR (5000)
SET #sql = 'Select * from tempdb.dbo.##temp_Query'
DECLARE #dbName1 VARCHAR (100)
IF OBJECT_ID ('tempDB..##TempExport_Query1','U') is not null
DROP TABLE ##TempExport_Query1
IF OBJECT_ID ('tempDB..##TempExport_Query2','U') is not null
DROP TABLE ##TempExport_Query2
SELECT #dbName1 = #dbName
SELECT #dbName = 'use ' + #dbName + ';'
DECLARE #columnNames VARCHAR (8000), #columnConvert VARCHAR (8000), #tempSQL VARCHAR (8000)
SELECT
#tempSQL = LEFT(#sql, CHARINDEX('from', #sql) - 1) + ' into ##TempExport_Query1 ' +
SUBSTRING(#sql, CHARINDEX('from', #sql) - 1, LEN(#sql))
EXEC (#dbName + #tempSQL)
--SELECT *
--FROM tempdb.INFORMATION_SCHEMA.Columns
--WHERE table_name = '##TempExport_Query1'
SELECT #columnNames = COALESCE(#columnNames + ',', '') + '"' + column_name + '"',
#columnConvert = COALESCE(#columnConvert + ',', '') + 'convert(nvarchar(4000),'
+ '[' + column_name + ']' + CASE
WHEN data_type IN ('datetime', 'smalldatetime') THEN ',121'
WHEN data_type IN ('numeric', 'decimal') THEN ',128'
WHEN data_type IN ('float', 'real', 'money', 'smallmoney') THEN ',2'
WHEN data_type IN ('datetime', 'smalldatetime') THEN ',120' ELSE ''
END + ') as ' + '[' + column_name + ']'
FROM tempdb.INFORMATION_SCHEMA.Columns
WHERE table_name = '##TempExport_Query1'
-- execute select query to insert data and column names into new temp table
SELECT #sql = 'select ' + #columnNames + 'temp##SortID into ##TempExport_Query2 from (select ' + #columnConvert + ',
''2'' as temp##SortID
from ##TempExport_Query1 union all select ''' + REPLACE(#columnNames, ',', ''', ''') + ''',
''1'') t '
EXEC (#sql)
SET #sql = 'bcp " select * from ##TempExport_Query2 ORDER BY temp##SortID " queryout "' + #FilePath +
'" -U uno -P uno -c -T -S ' + #server
EXEC master..xp_cmdshell #sql
SET #OutPut_Number = 1
END TRY
BEGIN CATCH
--DECLARE #ErrorDescription VARCHAR(1000) = 'ERROR - ' + ERROR_MESSAGE()
-- RAISERROR(#ErrorDescription,16,1)
SET #OutPut_Number = 2
--SET #OutPut_Message = ##ERROR
END CATCH
End
Parameters
DECLARE #OutPut_Number INT;
DECLARE #OutPut_Message VARCHAR(1000);
EXECUTE dbo.Copy_DataDump_SpecificQuery 'SELECT O.ID AS SystemNumber
,'' AS ManualNumber
,O.Date AS InvoiceDate
,OT.ID AS CustomerCode
,OT.Name AS CustomerName
,I.ID AS ItemID
,I.Description AS Item
,OL.UnitQty
,OL.FreeQty
,OL.UnitPrice
,OL.GrossValue
,NetSaleValue
,DueDate = ''
,A.ID AS SalesRepCode
,ItemCostPrice = OL.UnitPrice
FROM TxnOrder O
INNER JOIN TxnOrderLine OL ON O.UID = OL.TxnOrderUID AND O.SiteUID = Ol.TxnOrder_SiteUID
INNER JOIN Outlet OT ON O.OutletUID = OT.UID
INNER JOIN Item I ON OL.ItemUID = I.UID
INNER JOIN Agent A ON O.AgentUID = A.UID
WHERE O.mpt_TypeEnum = 1
AND( O.IsPrinted = 1 OR O.mpt_SalesmodelEnum = 2)
--AND O.Date >= #StartDate AND O.Date <= #EndDate
--AND (#DistributorUID IS NULL OR O.DistributorUID = #DistributorUID)
--AND (#AgentUID IS NULL OR O.AgentUID = #AgentUID)'
,#OutPut_Number OUTPUT
,#OutPut_Message OUTPUT
SELECT #OutPut_Message
After I execute I receive the following Output on the SQL Output window
69111E97-BEDE-4BDE-9EBE-C063DB690E9F.xls
I have created the permission for the folder as per below screenshot

This Problem was resolved ,I Logged in to the server via RDP and I executed the SP as per below and it worked out..
DECLARE #OutPut_Number INT;
DECLARE #OutPut_Message VARCHAR(1000);
EXECUTE dbo.Copy_DataDump_SpecificQuery 'SELECT O.ID AS SystemNumber
,O.Date AS InvoiceDate
,OT.ID AS CustomerCode
,OT.Name AS CustomerName
,I.ID AS ItemID
,I.Description AS Item
,OL.UnitQty
,OL.FreeQty
,OL.UnitPrice
,OL.GrossValue
,NetSaleValue
,A.ID AS SalesRepCode
,ItemCostPrice = OL.UnitPrice
FROM TxnOrder O
INNER JOIN TxnOrderLine OL ON O.UID = OL.TxnOrderUID AND O.SiteUID = Ol.TxnOrder_SiteUID
INNER JOIN Outlet OT ON O.OutletUID = OT.UID
INNER JOIN Item I ON OL.ItemUID = I.UID
INNER JOIN Agent A ON O.AgentUID = A.UID
WHERE O.mpt_TypeEnum = 1
AND( O.IsPrinted = 1 OR O.mpt_SalesmodelEnum = 2)'
,#OutPut_Number OUTPUT
,#OutPut_Message OUTPUT
SELECT #OutPut_Message
AND In My select Query I removed the Following Columns
'' AS ManualNumber
DueDate = ''
AND as Im already have the permission to access the server via RDP,I replaced the following path as follows
SET #FilePath = '\\ComputerName\Users\MyUserName\Downloads\Exel_File' + #Output_FIleName
C:\Users\Pathuma\Downloads\Excel
SET #FilePath = '\C:\Users\MyUsername\Downloads\Excel' + #Output_FIleName

Related

ADF dynamic mapping syntax error in the Pipeline Expression Builder

I am getting the Syntax error: Missing comma between arguments
What can I try to resolve the issue ?
set #sqltext2 = ''{''
select #sqltext2 = #sqltext2 + ''"source": {"name": "' + replace(column_name,' ','_') + '"}''
from adf_pipeline_columns
where data_source = #data_source
and schema_name = #schema_name
and table_name = #table_name
and column_ordinal = #mincol
and active = 1
select #sqltext2 = #sqltext2 + ''"sink": {"name": "' + replace(column_name, ' ', '_') + '"}''
from adf_pipeline_columns
where data_source = #data_source
and schema_name = #schema_name
and table_name = #table_name
and column_ordinal = #mincol
and active = 1
set #sqltext2 = case #sqltext2 when '''' then '''' else #sqltext2 + (case when #mincol = #maxcol then ''}'' else ''},'' end) end
set #sqltext = #sqltext + #sqltext2
set #sqltext2 = ''''
set #mincol = #mincol + 1
end
set #sqltext = #sqltext + ''
]
}''
select #sqltext as extract_query
')
Tried paging through the errors in ADF pipeline expression builder, but do not understand the cause of the error.

Create database if already exists using QUOTENAME

conn = pyodbc.connect("DRIVER={SQL Server};"
"SERVER="+server+";"
"UID="+username+";"
"PWD="+password,
autocommit=True)
cursor = conn.cursor()
database= "abcd"
sql_create = (
"DECLARE #sql AS NVARCHAR(MAX);"
"SET #sql = 'if not exists(select * from sys.databases where name = ' + QUOTENAME(?) + ')' + ' CREATE DATABASE ' + QUOTENAME(?);"
"EXEC sp_executesql #sql")
cursor.execute(sql_create,database,database)
Getting error msg like pyodbc.ProgrammingError: ('42S22', u"[42S22] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Invalid column name 'abcd'. (207) (SQLExecDirectW)")"
Don't use QUOTENAME and concatenation for the WHERE clause parameter. Also, avoid using the legacy SQL Server ODBC driver that ships with Windows to access Azure SQL Database. Instead, download and use a newer ODBC driver. Below is an example with these changes.
conn = pyodbc.connect("DRIVER={ODBC Driver 17 for SQL Server};"
"SERVER="+server+";"
"UID="+username+";"
"PWD="+password,
autocommit=True)
cursor = conn.cursor()
database= "abcd"
sql_create = (
"DECLARE #sql AS NVARCHAR(MAX);"
"SET #sql = N'if not exists(select * from sys.databases where name = #DatabaseName)' + N' CREATE DATABASE ' + QUOTENAME(?) + N';';"
"EXEC sp_executesql #sql, N'#DatabaseName sysname', #DatabaseName = ?;")
cursor.execute(sql_create,database,database)
You could also declare a T-SQL variable for the database name and assign it to the parameter value so that you only need to pass a single parameter:
sql_create = (
"DECLARE #sql AS NVARCHAR(MAX);"
"DECLARE #DatabaseName sysname = ?;"
"SET #sql = N'if not exists(select * from sys.databases where name = #DatabaseName)' + N' CREATE DATABASE ' + QUOTENAME(#DatabaseName) + N';';"
"EXEC sp_executesql #sql, N'#DatabaseName sysname', #DatabaseName = #DatabaseName;")
cursor.execute(sql_create,database)

Insert the data into the remote table from # temp table in the stored procedure

I have a stored procedure in AZURE SQL database.In that there is a requirement to insert the records into the remote table from #temp table.
As xxxx_table is in the remote database used sp_execute_remote.
below is the scenario:
Create Procedure SP1 parameter1, Parameter2
As
select Distinct B.column1, B.Column2
into #A
from (Query1
Union
Query2) B
if (select count(1) from #A) > 0
Begin
Exec sp_execute_remote #data_source_name = N'Remotedatabase',
#stmt = N'INSERT INTO [dbo].[xxxx_table]
SELECT DISTINCT
'xxx' AS 'column1',
'xxx as 'Column2',
'xxx' AS 'Column3',
'xxx' AS 'Column4',
'xxx' AS Column4
FROM #A A INNER JOIN table1 on A.Column1 = Table1.Column2'
End
)
Getting the syntax error as below:
Incorrect syntax near 'xxx'.
Where am i going wrong? or let me know if there is another way to achieve this.
If you need to dynamically build a string in SQL single-quote the whole sentence, or use 'some text' + 'another text' to concat sentences. If you must add single quote use a double single quote ''
Example:
DECLARE #param1 int;
DECLARE #param1 VARCHAR(10);
SET #param1 = 10;
SET #param2 = 'CCDOS87'
#Stmt = 'SELECT Field1 FROM TableName WHERE Field1 = '
+ CAST(#param1 AS VARCHAR(100))
+ ' AND Field1 = '''
+ param2
+ ''''; <- This is a single '
#stmt = N'INSERT INTO [dbo].[Error_table]
SELECT DISTINCT
xxx AS column1,
xxx as Column2,
xxx AS Column3,
xxx AS Column4,
xxx AS Environment
FROM #A A INNER JOIN table1 on A.Column1 = Table1.Column2'
update
If your tables are in different databases but in the same server use:
INSERT INTO SERVER.SCHEMA.TABLE_NAME
SELECT Something
FROM SERVER.SCHEMA.TABLE_NAME

Dynamic Pivot without Null value

This is a dynamic crosstab query in Northwind database:
DECLARE #COUNTRY NVARCHAR(MAX) ='', #COUNTRY2 NVARCHAR(MAX)
SELECT #COUNTRY = #COUNTRY + QUOTENAME(Country)+', '
FROM Customers
GROUP BY Country
SET #COUNTRY= LEFT(#COUNTRY, LEN(#COUNTRY)-1)
SET #COUNTRY2 = REPLACE(#COUNTRY, ',' , '+')
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = 'SELECT * , '+#COUNTRY2+' AS TOTAL
FROM (SELECT E.EmployeeID, E.LastName,
ISNULL( OD.Quantity, 0)* ISNULL(OD.[UnitPrice],0) QU,
O.ShipCountry AS CO
FROM Orders O JOIN Employees E ON O.EmployeeID = E.EmployeeID
JOIN [dbo].[Order Details] OD ON OD.OrderID = O.OrderID) AS T
PIVOT(SUM(QU) FOR CO IN ('+#COUNTRY+')) AS PVT
ORDER BY 1'
EXEC(#SQL)
I need to change the code in a way that have Null values replaced by 0.
DECLARE #COUNTRY NVARCHAR(MAX) = '' ,
#COUNTRY2 NVARCHAR(MAX);
SELECT #COUNTRY = #COUNTRY + COALESCE(QUOTENAME(Country) + ', ', '')
FROM Customers
WHERE EXISTS ( SELECT *
FROM [Orders] AS [o]
WHERE o.[CustomerID] = Customers.[CustomerID] )
GROUP BY Country;
SET #COUNTRY = LEFT(#COUNTRY, LEN(#COUNTRY) - 1);
SET #COUNTRY2 = REPLACE(#COUNTRY, ',', '+');
DECLARE #SQL NVARCHAR(MAX);
SET #SQL = 'SELECT * , ' + #COUNTRY2 +
' AS TOTAL
FROM (
SELECT oe.EmployeeID, oe.LastName, oe.ShipCountry AS CO,
COALESCE(OD.Quantity * OD.UnitPrice, 0) AS QU
FROM (
SELECT EmployeeID, LastName, ShipCountry
FROM (
SELECT DISTINCT
ShipCountry
FROM Orders
) o ,
Employees
) oe
LEFT JOIN Orders O ON O.EmployeeID = oe.EmployeeID AND
[oe].[ShipCountry] = [O].[ShipCountry]
LEFT JOIN [Order Details] OD ON OD.OrderID = O.OrderID
) AS T
PIVOT(SUM(QU) FOR CO IN (' + #COUNTRY + ')) AS PVT
ORDER BY 1';
EXEC(#SQL);
You need to change the SELECT * to:
SELECT ISNULL(Argentina,0) AS 'Argentina' , INSNULL(Belgium,0) AS 'Belgium' , ....
Ofcourse, you would need to change your dynamic query to reflect the ISNULL functions.
Good Luck

Replacement for "select * into" in sql azure?

I need a way to generically take a table and copy its data into a new table--basically the same thing that SELECT * INTO does in regular SQL Server. Is there a way to do this in SQL Azure? I only have the existing and new table names at this point.
I encountered the same problem and the author's answer is not very detailed, so I will give some more information, on how i solved it.
I needed to duplicate tables that start with a given prefix ('from_') into new tables with prefix ('to_').
Generate CREATE Statement
I use this query (found on stackoverflow) to generate all CREATE statements, for every table that starts with 'from_' prefix.
select 'create table [' + so.name + '] (' + o.list + ')' + CASE WHEN tc.Constraint_Name IS NULL THEN '' ELSE 'ALTER TABLE ' + so.Name + ' ADD CONSTRAINT ' + tc.Constraint_Name + ' PRIMARY KEY ' + ' (' + LEFT(j.List, Len(j.List)-1) + ')' END as query
OBJECTPROPERTY(object_id(TABLE_NAME), 'TableHasIdentity') as tablehasidentity
from sysobjects so
cross apply
(SELECT
' ['+column_name+'] ' +
data_type + case data_type
when 'sql_variant' then ''
when 'text' then ''
when 'ntext' then ''
when 'decimal' then '(' + cast(numeric_precision as varchar) + ', ' + cast(numeric_scale as varchar) + ')'
else coalesce('('+case when character_maximum_length = -1 then 'MAX' else cast(character_maximum_length as varchar) end +')','') end + ' ' +
case when exists (
select id from syscolumns
where object_name(id)=so.name
and name=column_name
and columnproperty(id,name,'IsIdentity') = 1
) then
'IDENTITY(' +
cast(ident_seed(so.name) as varchar) + ',' +
cast(ident_incr(so.name) as varchar) + ')'
else ''
end + ' ' +
(case when IS_NULLABLE = 'No' then 'NOT ' else '' end ) + 'NULL ' +
case when information_schema.columns.COLUMN_DEFAULT IS NOT NULL THEN 'DEFAULT '+ information_schema.columns.COLUMN_DEFAULT ELSE '' END + ', '
from information_schema.columns where table_name = so.name
order by ordinal_position
FOR XML PATH('')) o (list)
left join
information_schema.table_constraints tc
on tc.Table_name = so.Name
AND tc.Constraint_Type = 'PRIMARY KEY'
cross apply
(select '[' + Column_Name + '], '
FROM information_schema.key_column_usage kcu
WHERE kcu.Constraint_Name = tc.Constraint_Name
ORDER BY
ORDINAL_POSITION
FOR XML PATH('')) j (list)
where xtype = 'U'
AND name NOT IN ('dtproperties') AND name like 'from_%'
This query results in a set of values:
['query'] = create table [from_users_roles] ( [uid] int NOT NULL DEFAULT ((0)), [rid] int NOT NULL DEFAULT ((0)), )ALTER TABLE from_users_roles ADD CONSTRAINT from_users_roles_pkey PRIMARY KEY ([uid], [rid])
['tablehasidentity'] = 1 or 0
Now replace the prefixes in the query 'from_' with 'to_' and the CREATE Statement is finished:
create table [to_users_roles] ( [uid] int NOT NULL DEFAULT ((0)), [rid] int NOT NULL DEFAULT ((0)), )ALTER TABLE to_users_roles ADD CONSTRAINT to_users_roles_pkey PRIMARY KEY ([uid], [rid]);
Create INSERT Statement
When you want to insert data from one table to another, you have to distinguish between two cases:
TablehasIdentity == 0
INSERT INTO to_users_roles SELECT * FROM from_users_roles
TablehasIdentity == 1
This case is a bit more complex. The statement requires a column list and IDENTITY_INSERT switched on.
DECLARE #Query nvarchar(4000)
DECLARE #columnlist nvarchar(4000)
// Result of this query e.g.: "[cid], [pid], [nid], [uid], [subject]"
SET #columnlist = (SELECT SUBSTRING((SELECT ', ' + QUOTENAME(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'from_users_roles' ORDER BY ORDINAL_POSITION FOR XML path('')), 3, 200000))
SET #query ='SET IDENTITY_INSERT to_users_roles ON; INSERT INTO to_users_roles (' + #columnlist + ') SELECT ' + #columnlist + ' FROM from_users_roles; SET IDENTITY_INSERT to_users_roles OFF'
exec sp_executesql #query;
This worked out for me pretty well.
The latest version of Azure SQL DB, now in Preview, supports the SELECT INTO syntax and no longer requires a clustered index. For a detailed description of its features, and how to use it, see http://azure.microsoft.com/en-us/documentation/articles/sql-database-preview-whats-new/
After doing more research, it looks like there is no simple way to do this. You basically have to read the table's schema information and create the new table based on that.
Select into is now supported SQL DB V12. Just upgrade your server and start using the syntax.
I found a clever trick on this blog
Instead of using "select into" use "insert select".
First you have to create the destination table. To do this, right click on the source table in SQL Management Studio, and choose "Script Table as" -> "Create To" -> "New Query Window".
Then, change the name of the table in the query, and execute the query. Below is an example where I have added today's date to the new table, calling it "Entities_2015_08_24" (the old table was called "Entities"):
CREATE TABLE [dbo].[Entities_2015_08_24](
[Url] [nvarchar](max) NULL,
[ClientID] [nvarchar](max) NULL
)
Then, do a "insert select" from the old table (Entities) into the new table (Entities_2015_08_24):
INSERT INTO [dbo].[Entities_2015_08_24]
([Url]
,[ClientID]
)
SELECT
[Url]
,[ClientID]
FROM [dbo].[Entities]
Q: Did you try it?
Q: Did you look at the SQL Azure documentation
ADDENDUM
AFAIK, you cannot use select into syntax to "clone" a table in Azure SQL. Because Azure requires a clustered index, and select into has no provision for defining one.
Details, and a potential workaround, are here:
http://blogs.msdn.com/b/windowsazure/archive/2010/05/04/select-into-with-sql-azure.aspx

Resources