I'm new to SSIS so forgive me if this question is trivial or has already been answered. So I have a SQL query that begins as follows:
declare #start datetime, #end datetime, #startMonth datetime, #endMonth datetime, #maxHoursToRespond int
----Set These------------------------------------------------
set #end='6/27/2014'
set #maxHoursToRespond=24
-------------------------------------------------------------
set #start=dateadd(dd, -90, #end) -- set duplication period
set #startMonth=dateadd(dd, -2, #end)-- set to start date of output you want
set #endMonth=dateadd(dd, -1, #end) -- set to day of end date of output you want
When I put this in my OLE DB Source Editor with SQL command as my data access mode,
all the variables are replaced with question marks.
It looks like :
DECLARE ? datetime, ? datetime, ? datetime, ? datetime, ? int
/*--Set These------------------------------------------------*/ SET ? = ?
SET ? = 24
/*-----------------------------------------------------------*/ SET ? = dateadd(dd, - 90, ?)
SET ? = dateadd(dd, - 2, ?)
SET ? = dateadd(dd, - 1, ?)
In the query builder.I'd like to know why this is happening.I'd also like to know how I can allow the query to be successfully built
(currently I get a syntax error of "The Declare SQL construct or statement is not supported.").
Do I have to create these variables (like #start) in SSIS itself?
You can:
Encapsulate your SQL in a stored procedure that contains all of the declarations internally (assuming the variable values are static), then call the stored procedure in the execute SQL task with EXEC. EXEC My_Stored_Procedure
Write a stored procedure that accepts the variables as inputs, map them to variables in SSIS, then execute the stored procedure like this Exec My_Stored_Proc ?,?,?,? with the user variables mapped to the corresponding stored procedure variables.
Leave the query as is, but remove the DECLARE and the SETs, and map the SSIS variables to the query. This most likely will not work, because SSIS will not know which ? corresponds with which variable (it will try to map them in the order they appear.
Number 2 is the generally accepted method, unless you store your variable values in a table or something that the SP in number can access, in which case number 1 may be cleaner.
I have pasted straight to SQL command text yours script in OLE DB Source Editor and nothing changed in it. By pressing Parse Quesry.. I checked that SQL is correct. When I tried to use Build Query.., it said, that DECLARE is not supported. So don't use builder :)
Related
I have a Stored Procedure in SQL Server 2008 like below.
ALTER PROCEDURE myStoredProcedure
#Id int,
#hin varchar(30),
#checkValue varchar(30),
#CounterDeceasedPatients int=0 OUTPUT
insert into myTable
values (#Id, #hin, GETDATE())
if (#checkValue is not null)
BEGIN
set #CounterDeceasedPatients = #CounterDeceasedPatients + 1;
update myTable
set hin= #checkValue
where Id = #Id
RETURN;
END
I am calling this SP via SSIS, by using an OLE DB Command in Data Flow, which enables each rows in my file go to the SP - with the sql command: EXEC [dbo].[myStoredProcedure] ?,?,?. (The order of data (?) in my file is: Id, hin, checkValue)
What I want to do is to count how many different records (different rows) entered the if condition in my SP. SO I believe need to place a "row counter" somewhere, filtering its usage where #checkValue is not null. But I couldnt find it how. I am a newbie in SSIS, so I appreciate if someone helps me to figure this out. Thanks.
EDIT: I am trying to select only #checkValue as an input parameter for my ROW COUNT, but it is giving error:
EDIT2: I updated my SP. I added "CounterDeceasedPatients" variable as Int32 in SSIS and assigned it to 0. My sql execute command is: EXEC [dbo].[myStoredProcedure] ?,?,?,?,CounterDeceasedPatients
This is giving me the error:
Source: "Microsoft OLE DB Provider for SQL Server" Hresult:
0x80040E07 Description: "Error converting data type nvarchar to
int.".
When I use EXEC [dbo].[myStoredProcedure] ?,?,?,?,CounterDeceasedPatients output as SQL command, then I receive the error:
Description: "Cannot use the OUTPUT option when passing a constant to
a stored procedure.
I need help.
Use a script transformation and a DataFlow-level package variable.
Create the int-type variable with a default of 0, and in the script transformation, increment the variable if checkvalue is not null for the incoming row, and then use the value of the variable to set the value of your counter column.
Note that I am suggesting this INSTEAD of trying to update the counter with an OUTPUT variable in your stored procedure, and not as a way of trying to get that idea to work.
I am getting the following error when I execute my stored procedure:
Msg 102, Level 15, State 1, Line 6Incorrect syntax near '2011'.(1 row(s) affected)
Here is the stored procedure:
ALTER PROCEDURE [dbo].[DeliveryFileNames]
AS
BEGIN
SET NOCOUNT ON;
declare #SQL nvarchar(4000)
Create Table #DelivTemp(
Style nvarchar(50),
Material nvarchar(50),
Filename nvarchar(100),
delivered_date date)
set #SQL=
N'insert into #DelivTemp
Select distinct Style,Material,filename
from OPENQUERY(GCS_PRODUCTION,
''SELECT LEFT(FILENAME,locate(''''_'''',FILENAME)-1)as Style,
substring_index(filename,''''_'''',2)as Material,filename,
delivered_date FROM view_delivery_log
where delivered_date > ''2011%'' order by Style '')'
exec (#SQL)
drop table dbo.DelivFN
Select * into dbo.DelivFN
from #DelivTemp
END
I am using OpenQuery to update a SQL table from a linked server on SQL Server 2008 R2.
I know that the underscore is a real issue, but I have tried a plethora of options including \, % and both single and double quotes.
Regardless I am getting the same result. I can run the query independently of the stored procedure and achieve the correct results. The filename field referenced several times is formatted 00000000_ABC4_A.png. I am using the underscore to identify the components of the file name that I need for my reporting purposes.
In addition to the the logical error of your date comparison using the % that the others have pointed out, your current issue is a syntactical error.
Since you've got a dynamic sql statement contained within another dynamic sql statement... you'll need to double-escape all of your single quotes... which you did in most of the query, except for the following line:
where delivered_date > ''2011%'' order by Style '')'
Properly escaped, would be:
where delivered_date > ''''2011%'''' order by Style '')'
Which raises the question... why are you building up the string to execute dynamically, instead of just calling the statement directly?
It's the syntax of ''2011%''. This is not a valid date. % being a wildcard means the compiler can't know what to compare against in the WHERE clause. You'd need to use an actual date: i.e. ''2011_01_01'' so the compiler can know what to compare against
I believe the stored proc exec runs under a different session, therefore you won't have access to the temp table anyway. So, it won't matter if you get that sql statement to run. You could always use YEAR(delivered_date) > 2011.
Another approach would be to use the fqn for the linked server to select into and bypass the temp table all together:
SELECT LEFT(FILENAME,locate('_',FILENAME)-1)as Style,
substring_index(filename,'_',2)as Material,filename,delivered_date
FROM [linked_server_name].[db_name].[dbo].view_delivery_log
into dbo.DelivFN
Optimizer seems to be getting confused about the null-ability of a varchar parameter and I'm not sure I understand why. I'm using SQL Server 2008 btw. All columns being queried are indexed. The TDate column is a clustered, partitioned index. The FooValue column is indexed, non-nullable column.
Example:
CREATE PROCEDURE dbo.MyExample_sp #SDate DATETIME, #EDate DATETIME, #FooValue VARCHAR(50)
AS
SET NOCOUNT ON
--To avoid parameter spoofing / sniffing
DECLARE #sDate1 DATETIME, #eDate1 DATETIME
SET #sDate1 = #sDate
SET #eDate1 = #eDate
SELECT
fd.Col1,
fd.Col2,
fd.TDate,
fl.FooValue,
fd.AccountNum
FROM dbo.FooData fd
INNER JOIN dbo.FooLookup fl
ON fl.FL_ID = fd.FL_ID
WHERE fd.TDate >= #sDate1
AND fd.TDate < #eDate1
AND fl.FooValue = #FooValue
Running this as a query works as expected. All indexes are seeks, no spoofing etc. Running this by executing the sproc takes 20 times longer - same query - same parameters. However, if I make the following change (very last line) everything works again.
CREATE PROCEDURE dbo.MyExample_sp #SDate DATETIME, #EDate DATETIME, #FooValue VARCHAR(50)
AS
SET NOCOUNT ON
--To avoid parameter spoofing / sniffing
DECLARE #sDate1, #eDate1
SET #sDate1 = #sDate
SET #eDate1 = #eDate
SELECT
fd.Col1,
fd.Col2,
fd.TDate,
fl.FooValue,
fd.AccountNum
FROM dbo.FooData fd
INNER JOIN dbo.FooLookup fl
ON fl.FL_ID = fd.FL_ID
WHERE fd.TDate >= #sDate1
AND fd.TDate < #eDate1
AND fl.FooValue = ISNULL(#FooValue, 'testthis')
It's like the optimizer is getting confused about whether the parameter is nullable or not? Also, adding a default value to the parameter doesn't make any difference. It still takes forever for the sproc to run unless I use = isnull(#parameter, 'some constant')
I'm happy I figured this out. But, I'd like to understand why this is happening and if there was a more elegant way to resolve the issue.
Re: Nullable variables
There is no concept of nullable for variables in T-SQL, the way that you can define a variable as nullable in c# using the ?.
If you have a parameter in a stored procedure, the end user can pass whatever he or she wants into the stored procedure, be it a real value or a null.
Re: the query plan
The query plan that will get cached is the query plan that gets generated upon the first time you call this stored procedure.. so if you passed in a null for #FooValue the very first time you ran it, then it will be optimized for #FooValue = null.
There is an OPTIMIZE FOR hint that you can use to optimize the query for some other value:
Or you can use WITH RECOMPILE, which will force the query plan to get regenerated on every run of the stored procedure.
Obviously there are trade-offs when using these types of hints, so make sure you understand them before using them.
I have ssis package in that I'm taking values from flat file and insert it into table.
I have taken one Execute SQL Task in that creating one temptable
CREATE TABLE [tempdb].dbo.##temptable
(
date datetime,
companyname nvarchar(50),
price decimal(10,0),
PortfolioId int,
stype nvarchar(50)
)
Insert into [tempdb].dbo.##temptable (date,companyname,price,PortfolioId,stype)
SELECT date,companyname,price,PortfolioId,stype
FROM ProgressNAV
WHERE (Date = '2011-09-30') AND (PortfolioId = 5) AND (stype in ('Index'))
ORDER BY CompanyName
Now in above query I need to pass (Date = '2011-09-30') AND (PortfolioId = 5) AND (stype in ('Index'))
these 3 parameter using variable name I have created variables in package so that I become dynamic.
In your Execute SQL Task, make sure SQLSourceType is set to Direct Input, then your SQL Statement is the name of the stored proc, with questionmarks for each paramter of the proc, like so:
Click the parameter mapping in the left column and add each paramter from your stored proc and map it to your SSIS variable:
Now when this task runs it will pass the SSIS variables to the stored proc.
The EXCEL and OLED DB connection managers use the parameter names 0 and 1.
I was using a oledb connection and wasted couple of hours trying to figure out the reason why the query was not working or taking the parameters. the above explanation helped a lot
Thanks a lot.
Along with #PaulStock's answer, Depending on your connection type, your variable names and SQLStatement/SQLStatementSource Changes
https://learn.microsoft.com/en-us/sql/integration-services/control-flow/execute-sql-task
SELECT, INSERT, UPDATE, and DELETE commands frequently include WHERE clauses to specify filters that define the conditions each row in the source tables must meet to qualify for an SQL command. Parameters provide the filter values in the WHERE clauses.
You can use parameter markers to dynamically provide parameter values. The rules for which parameter markers and parameter names can be used in the SQL statement depend on the type of connection manager that the Execute SQL uses.
The following table lists examples of the SELECT command by connection manager type. The INSERT, UPDATE, and DELETE statements are similar. The examples use SELECT to return products from the Product table in AdventureWorks2012 that have a ProductID greater than and less than the values specified by two parameters.
EXCEL, ODBC, and OLEDB
SELECT* FROM Production.Product WHERE ProductId > ? AND ProductID < ?
ADO
SELECT * FROM Production.Product WHERE ProductId > ? AND ProductID < ?
ADO.NET
SELECT* FROM Production.Product WHERE ProductId > #parmMinProductID
AND ProductID < #parmMaxProductID
The examples would require parameters that have the following names:
The EXCEL and OLED DB connection managers use the parameter names 0 and 1. The ODBC connection type uses 1 and 2.
The ADO connection type could use any two parameter names, such as Param1 and Param2, but the parameters must be mapped by their ordinal position in the parameter list.
The ADO.NET connection type uses the parameter names #parmMinProductID and #parmMaxProductID.
A little late to the party, but this is how I did it for an insert:
DECLARE #ManagerID AS Varchar (25) = 'NA'
DECLARE #ManagerEmail AS Varchar (50) = 'NA'
Declare #RecordCount AS int = 0
SET #ManagerID = ?
SET #ManagerEmail = ?
SET #RecordCount = ?
INSERT INTO...
I have a function and select statement
CREATE FUNCTION dbo.fun_currentday ( #dt DATETIME)
RETURNS DATETIME
AS
BEGIN
DECLARE #currentday DATETIME
SET #currentday = DATEADD(dd, DATEDIFF(dd, 0, #dt), 0)
RETURN (#currentday)
END
GO
DECLARE #pvm AS DATETIME
SET #pvm = GETDATE()
SELECT 'Last 7 days' AS Range, dbo.fun_currentday(#pvm) - 6 AS Stday, dbo.fun_currentday(#pvm) AS Endday
All works fine but when I hover over dbo.fun_currentday at the select statement, I get an error saying:
Cannot find either column "dbo" or the user-defined function or aggregate "dbo.fun_currentday", or the name is ambiguous.
Where's the problem?
Intellisense / Error highlighting always does this for newly created objects. Use Ctrl+Shift+R to refresh the local cache.
Before
After
Everything runs fine here with SQL Server 2008 Express.
Have you tried running your query on a different database?
You can try to create a new schema and create you UDF in it.
Make sure you have the necessary permissions and that the dbo schema configuration is correct.
Your stored procedure have to be stored somewhere so when you don't specify the location it goes to default database (master). So you should call it like
SELECT 'Last 7 days' AS Range,master.dbo.fun_currentday(GETDATE()) - 6 AS Stday, master.dbo.fun_currentday(GETDATE()) AS Endday
EDITED
I've checked that and I wasn't right, it not always goes to mater schema. It goes to database in contex of you were woring, so if your create procedure was created in query on root folder it goes to master, but if you created it in query of test databse you should use test.dbo.fun_currentday(GETDATE()). To avoid it always specify the databse like USE database_name GO CREATE FUNCTION dbo.fun_currentday