SSIS OLEDB data transfer calling parametereized stored procedure | Columns not found - sql-server

I have a SQL server stored procedure which takes as parameter a part of the database name. It works perfectly when executing from SQL Server Management Studio.
However I need to call this SP from SSIS OLE DB Source component. When I specify the SQL command and parameters in the OLE DB Source component, I get the following error:
"Error at SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has
occurred. Error code: 0x80004005. An OLE DB record is available.
Source: "Microsoft SQL Server Native Client 10.0" Hresult: 0x80004005
Description: "The OLE DB provider "SQLNCLI10" for linked server does
not contain the table The table either does not exist or the current
user does not have permissions on that table.".: Unable to retrieve
column information from the data source. Make sure your target table
in the database is available".
Basically it cant find the table used by the stored procedure as the database name is parameterized. I searched around and found that OLE DB data source needs meta data for the table. How can I provide this?
This is my stored procedure:
USE [ILLP]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[OUTPUT_MI_Tyep12] #param1 varchar(5)
AS
BEGIN
SET FMTONLY OFF;
SET NOCOUNT ON;
declare #query varchar(1000)
set #query='
SELECT [M12]
,[T3Size]
,[SizeVCost]
,NULL as [DefaultTonnage]
,NULL as [IdleCost]
,NULL as [SuperLocoID]
,[IfAllowFleetSizeVio]
FROM [ServN\PROD2].[Scenario_' + #param1 +'_PRD].[dbo].[Para_LTYPE]'
exec(#query)
END

I am guessing you are trying to loop through different databases using the SP with a parameter in SSIS. However you could do this with a Select Command From variable source:
Create a new Variable - SELECT_OUTPUT_MI_Tyep12 for instance (String Type);
Within the variable properties check EvaluateAsExpression = True;
Under the Expression use the following:
SELECT [M12]
,[T3Size]
,[SizeVCost]
,NULL as [DefaultTonnage]
,NULL as [IdleCost]
,NULL as [SuperLocoID]
,[IfAllowFleetSizeVio]
FROM [ServN\\PROD2].[Scenario_" + #[User::DBNameParameter] + "_PRD].[dbo].[Para_LTYPE]
Change the #[User::DBNameParameter] for your specific one;
Use the SQL Command from variable in the connection manager, selecting the SELECT_OUTPUT_MI_Tyep12 variable.
This should allow you to gather all the Meta data back from the table and carry on with the rest of the data flow.

Related

Execute Stored Procedure with multiple result sets

I am using SSIS 2016. I need to execute a stored procedure that returns 4 result sets. I only need to keep the first result set and write this to a table. I can not modify the stored procedure. I do not care about any of the data returned in the other result sets. The stored procedure is in a SQL Server 2016 database. Results will also reside in SQL Server 2016.
I currently have this process running in SSIS 2008 using the "SQL Command" data access mode in an OLE DB Source like below. I have this in a For Each Loop Container to pass a series of param values to the stored procedure as I execute it multiple times for different param values on a daily basis.
SET FMTONLY OFF;
EXEC myProc
#Param1 = ?,
#Param2 =?,
#Param3 = ?;
By default SSIS 2008 is only returning the first result set, which has worked for me as I only care about the first result set.
I am using the Native OLEDB SQL Server client. From what I have read, it has changed the way it handles multiple result sets. I have used the WITH RESULT SETS to define the first result set but if I execute SSIS will fail indicating other result sets need to be defined.
In short, what is the best approach to duplicate what works in SSIS 2008 in SSIS 2016?
Solution Overview
I made 2 Experiments on that issue, the first experiments showed that in case of stored procedures with no parameters, nothing changed in SQL Server 2016 and SSIS 2016, the first Result Set is returned and others are ignored.
The second experiment showed that when using parameters, this will throw an exception, so you have to define metadata using WITH RESULT SETS option, then remove this option.
Detailed Solution
Experiment 1
The following experiment are made using SQL Server 2016 and Visual Studio 2015 with SSDT 2016
First i created this stored procedure
CREATE PROCEDURE sp_Test
AS
BEGIN
SET NOCOUNT ON;
SELECT TOP 10 PersonType,NameStyle,Title
FROM [AdventureWorks2016CTP3].[Person].[Person]
SELECT TOP 10 PersonType,Firstname,Lastname
FROM [AdventureWorks2016CTP3].[Person].[Person_json]
END
GO
Then i added a Data flow task to SSIS package
Added an OLEDB Source, Recordset destination
In OLEDB source i select the Data access mode to SQL command
an use the following commnad
EXEC sp_Test
When clicking on Columns Tab it shows the first ResultSet structure
And we i executed the package it runs succesfully
Experiment 2
I changed the stored procedures to the following:
ALTER PROCEDURE [dbo].[sp_Test]
#param1 varchar(10),
#param2 varchar(10),
#param3 varchar(10)
AS
BEGIN
SET NOCOUNT ON;
SELECT TOP 10 PersonType,NameStyle,Title ,#param2 as 'Param'
FROM [AdventureWorks2016CTP3].[Person].[Person]
SELECT TOP 10 PersonType,Firstname,Lastname,#param3 as 'Param'
FROM [AdventureWorks2016CTP3].[Person].[Person_json]
END
And i used the following SQL Command in the OLEDB Source:
EXEC sp_Test ?,?,?
WITH RESULT SETS (
(
PersonType NVarchar(10),
NameStyle NVarchar(10),
Title NVarchar(10),
Param Varchar(10)
)
)
And i mapped the parameters correctly.
When running the package it throws the following exception.
[OLE DB Source 2] Error: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80040E14.
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 11.0" Hresult: 0x80040E14 Description: "EXECUTE statement failed because its WITH RESULT SETS clause specified 1 result set(s), and the statement tried to send more result sets than this.".
After that i tried to remove the With RESULT SETS option, so the command is :
EXEC sp_Test ?,?,?
I tried to execute the package again, so it is executed with no errors.
Conclusion
Try to use the WITH RESULT SETs option to define the OLEDB Source metadata, after that the metadata is defined, just remove this option and run the package, so it will just take the first Result Set succesfully.
I know it's not exactly what you are asking for, but maybe you could create another stored proc that will return only the first result set for you? (Without touching the first stored proc.) Or insert the data into a table for you and then you just read the data?

How to EXEC a stored procedure from SSIS to get its output to text file

I wrote a stored procedure that reads records into a temp table and then creates a pivoted output from the data in the temp table.
Running the stored procedure from SSMS works just fine. What I am facing problems is now that I am trying to create the SSIS package that will execute the sproc, and write its output to a tab delimited text file.
I am using Visual Studio 2015. My first problem is that when I try to configure the OLE DB Source within the Data Flow Task, when adding the SQL Command inside the SQL Command Text box: EXEC ShopperSkuHistory and click OK, I get this error:
I have been looking for information about this error, but I have not found anything that helps me understand why this is happening, and how I can fix it.
I hope through this post I can learn how to fix this error.
Thank you much in advance.
Here is my sproc:
UPDATED CODE
ALTER PROCEDURE [dbo].[ShopperSkuHistory]
AS
BEGIN
IF OBJECT_ID('tempdb..[#ShopperSku_History_Load]') IS NOT NULL
BEGIN
DROP TABLE [#ShopperSku_History_Load];
END;
-- Create main table
CREATE TABLE [#ShopperSku_History_Load]
(
[ID] INT IDENTITY(1, 1) NOT NULL
, [shopper_id] CHAR(32) NOT NULL
, [sku] VARCHAR(100) NOT NULL
, time_added DATETIME
)
SET NOCOUNT ON;
-- Populate the table
INSERT INTO [#ShopperSku_History_Load] ([shopper_id], [sku], [time_added])
SELECT DISTINCT [cr].[shopper_id], LEFT([cri].[sku], 9) [sku], GETDATE() [time_added]
FROM [dbo].[receipt_item] [cri]
INNER JOIN [dbo].[receipt] [cr]
ON [cri].[order_id] = [cr].[order_id]
WHERE[cri].[list_price] > 0
AND [cri].[IsInitialPurchase] = 1
AND LEFT([cri].[sku], 3) = 'MN0'
AND ([cr].[date_entered] > DATEADD(YEAR, -2, GETDATE()))
AND EXISTS (SELECT 1 FROM [product] [cp] WHERE [cp].[pf_id] = [cri].[sku] AND [cp].[for_sale] = 1)
AND NOT EXISTS (SELECT 1 FROM [dbo].[shopper] [cs] WHERE [cs].[IsTesting] = 1 AND [cs].[shopper_bounce] = [cr].[shopper_id])
ORDER BY [shopper_id];
CREATE TABLE [#HistoryOutput]
(
[shopper_id] VARCHAR(32)
, skus TEXT
)
INSERT INTO [#HistoryOutput]
( [shopper_id], [skus] )
SELECT
[shopper_id]
, STUFF(( SELECT ', ' + ISNULL([a].[sku], '')
FROM [#ShopperSku_History_Load] [a]
WHERE [a].[shopper_id] = [b].[shopper_id]
FOR
XML PATH('')
), 1, 1, '') [skus]
FROM [#ShopperSku_History_Load] [b]
GROUP BY [shopper_id];
SELECT
[shopper_id]
, [skus]
FROM
[#HistoryOutput];
END;
UPDATED ERROR
Exception from HRESULT: 0xC0202009
Error at Data Flow Task [OLE DB Source [1]]: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80040E14.
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 11.0" Hresult: 0x80040E14 Description: "Statement(s) could not be prepared.".
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 11.0" Hresult: 0x80040E14 Description: "Incorrect syntax near 'shopper_id'.".
This error
The metadata could not be determined because statement 'EXEC
XXXXXX' in procedure 'XXXXXX' contains dynamic SQL.
Consider using the WITH RESULT SETS clause to explicitly describe the
result set.
happens because the SP contains either a
Temp table
Dynamic SQL
Because of these dynamic elements, SSIS/SSDT has trouble getting the column metadata correctly. More info here. We need to help SSIS get that column metadata. Depending on your SQL Server version, there are two solutions.
For SSIS/SQL 2008, you can try setting FMTONLY OFF
For SSIS/SQL 2012, you can wrap the stored procedure with a RESULT SET from SSIS. Try this ...
Other options include updating the Stored Procedure itself and adding a WITH RESULTS SETS clause. Or updating the stored procedure to return a table variable.

Error: CLI0115E Invalid cursor state. SQLSTATE=24000

I'm trying to execute an SQL Server stored procedure using the execute SQL task of an SSIS package and I'm getting errors.
CLI0115E Invalid cursor state. SQLSTATE=24000
Cannot fetch a row from OLE DB provider "xxx.xxx" for linked
server "xxxxx".". Possible failure reasons: Problems with the query,
"ResultSet" property not set correctly, parameters not set correctly,
or connection not established correctly.
The stored procedure inserts data to a temp table and it contains a query with a join to db2 server. I'm using OPENQUERY to connect to the db2 database.
Example:
select column1, column2, column3 from OPENQUERY(#databasename,'select col1, col2, col3 from db2table1 where col3=xx') as qry1
join sqltable1 on qr1.col1 = sqltable1=col1
The SSIS package is supposed to run in loops and each time the stored procedure is supposed to return nearly 500 records. The error happens intermittently and doesn't occur when the stored procedure is run manually using SQL Server Management studio.
Any help would be much appreciated.

SSIS + Temp Table

I am having a stored proc which return 2 records and which contains a select statement from a temp table, So when i used this stored proc inside a OLEDB Source in SSIS and just trying to insert the set of records into a destination SQL table using OLEDB destination.
Its throwing a ERROR at source side saying :
[OLE DB Source [1661]] Error: A rowset based on the SQL command was not returned by the OLE DB provider.
Moreover tried with set nocount on and with SET FMTONLY OFF
But of no avail...........
Need help in this.........
I had a similar problem before and it was due to SSIS not being able to determine the output for dynamic SQL. I solved it by including a "fake" Select statement at the top of the query that matched the expected output. i.e.
CREATE PROCEDURE MyStoredProc
AS
SELECT 1 As Field1, 2 As Field2, 3 As Field3 -- list of fields of appropriate type
WHERE 1 = 0 -- so nothing is actually returned
-- Real SQL goes here.
GO
Please use same connection and , make delay validation=true

Import DBF files into Sql Server

I need a little help figuring this out because I'm new to stored procedures. I am trying to import a .DBF table into Sql Server 2008 using this store procedure.
CREATE PROCEDURE spImportDB
-- Add the parameters for the stored procedure here
AS
BEGIN
-- Insert statements for procedure here
SELECT * into Products
FROM OPENROWSET('vfpoledb','C:\Users\Admin\Doc\Data\DBF',
'SELECT * FROM MyTable')
END
GO
I receive this error.
The OLE DB provider "vfpoledb" has not been registered.This isn't true, I've installed it and it works fine in my other application.
I've also tried running it this way with this provider but I receive this error message
Cannot initialize the data source object of OLE DB provider "Microsoft.Jet.OLEDB.4.0" for linked server "(null)".
CREATE PROCEDURE spImportDB
-- Add the parameters for the stored procedure here
AS
BEGIN
-- Insert statements for procedure here
SELECT * into Products
FROM OPENROWSET('Microsoft.Jet.OLEDB.4.0','C:\Users\Admin\Doc\Data\DBF',
'SELECT * FROM MyTable')
END
GO
What's the easiest way to create this stored procedure? I want it to be a stored procedure not a wizard or program so please don't give me any programs.
You can try
SELECT * into SomeTable
FROM OPENROWSET('MSDASQL', 'Driver=Microsoft Visual FoxPro Driver;
SourceDB=\\SomeServer\SomePath\;
SourceType=DBF',
'SELECT * FROM SomeDBF')
from this previous question
I'm not sure about the "friendly-name" for VFPOLEDB, but the second SP should work (i.e. using 'Microsoft.Jet.OLEDB.4.0') as long as you're pointing to a specific DBF file by name. It looks like you're pointing to a directory, not the actual file.
Further information may be found in:
http://msdn.microsoft.com/en-us/library/ms190312.aspx
For anyone else looking for an answer to this, the cause of this error is installing the Foxpro driver for "Just Me" instead of "Everyone".
Run the installer for "Everyone" to avoid this error.

Resources