How to Log Number of Rows affected by SSIS Execute SQL Task - sql-server

When I execute a sql statement like "Select ...", I can only see "...100%" completed...
I want to log the number of rows affected.
How can we do that?

run your SELECT from within a stored procedure, where you can log the rowcount into a table, or do anything else to record it...
CREATE PROCEDURE SSIS_TaskA
AS
DECLARE #Rows int
SELECT ... --your select goes here
SELECT #Rows=##ROWCOUNT
INSERT INTO YourLogTable
(RunDate,Message)
VALUES
(GETDATE(),'Selected '+CONVERT(varchar(10),ISNULL(#Rows,0))+' rows in SSIS_TaskA')
GO

When you use a SQL Task for a select most of the time you give as destination a DataSet Object, you can count the number of ligne from the DataSet

I believe you could leverage a t-sql output clause on your update or insert statement and capture that as an ssis variable....or just drop it into a sql table.
here is an example...its crappy, but it is an example
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25
OUTPUT INSERTED.EmployeeID,
DELETED.VacationHours,
INSERTED.VacationHours,
INSERTED.ModifiedDate
INTO #MyTableVar;
You could output ##ROWCOUNT anyplace you need it to be.
Here is output syntax
http://technet.microsoft.com/en-us/library/ms177564.aspx

Related

Why is the table inside a non-met IF being validated before condition is met, resulting in error if table does not exist?

I am trying to execute a procedure with a parameter, and depending on the value of the parameter, three different IF conditions will be evaluated to verify which query it will execute from a linked server.
But when I execute the query, it seems to be checking if the tables inside all the IF exists before starting the query. And I know that only one of the table exists, that is why I am using the parameter, so it shouldn't fail. but I anyhow get the following error:
Msg 7314, Level 16, State 1, Line 25
The OLE DB provider "Microsoft.ACE.OLEDB.16.0" for linked server "LinkedServer" does not contain the table "D100". The table either does not exist or the current user does not have permissions on that table.
So in this code, assume that the parameter is 300. then I get the message above.
Do you know, if there is a way, to limit the query to do not check all the tables, but only the one where the IF condition will be met?
ALTER PROCEDURE[dbo].[Import_data]
#p1 int = 0
AS
BEGIN
SET NOCOUNT ON;
IF(#p1 = 100)
BEGIN
DROP TABLE IF EXISTS Table1
SELECT [Field1], [Field2], [Field3], [Field4], [Field5], [Field6]
INTO Table1
FROM[LinkedServer]...[D100]
END
IF(#p1 = 200)
BEGIN
DROP TABLE IF EXISTS Table2
SELECT[Field1], [Field2], [Field3], [Field4], [Field5], [Field6]
INTO Table2
FROM[LinkedServer]...[D200]
END
IF(#p1 = 300)
BEGIN
DROP TABLE IF EXISTS Table3
SELECT[Field1], [Field2], [Field3], [Field4], [Field5], [Field6]
INTO Table3
FROM[LinkedServer]...[D300]
END
END
I have tried googling it, but I found mostly workarounds as running a sub procedure, but it is not really a clean solution, I think.
Okay, it seems I that I found the answer. Even with an IF statement, the SQL Server validates the entire query before executing it, so the way to overcome it, is to use a Dynamic SQL Query.
"SQL Server Dynamic SQL is a programming technique that allows you to construct SQL statements dynamically at runtime. It allows you to create more general purpose and flexible SQL statement because the full text of the SQL statements may be unknown at compilation."
This is how the query looks now. so instead of multiple IF statements, the query changes dynamically depending on the parameter.
DECLARE #SQL NVARCHAR(MAX)
SET #SQL = N'DROP TABLE IF EXISTS Table1;
SELECT [Field1]
,[Field2]
,[Field3]
,[Field4]
,[Field5]
,[Field6]
INTO Table1
FROM [LinkedServer]...[D' + CONVERT(nvarchar(3),#p1) + N']'
EXEC sp_executesql #SQL

Log for affected rows of select and insert command - SQL Server- Help needed

so I have some commands which I want to put in a stored procedure(then stored procedure executed by a job) to automate. What I need is to make some sort of log(file or table?!) where to have the affected rows a select or insert did and also how long they took to execute. So can you help me with some ideas? thanks
Examples below:
truncate table table_xyz
insert into table_aaa
select * from (select * from table_dsd union all select * from table_dsdf)
ex: "40234 rows affected" ; 00:00:35
some selects
one simple way would be to do like this
declare #startdate datetime=getdate()
select * from sometbl
--log data
select ##rowcount,datediff(minute,#startdate,getdate())

Looping through records with SQL server

Being an MS Access bod, our IT group doesn't let me touch the SQL server much so I don't know how to do looping of recordsets in it for a scheduled job I need. I have pseudo-coded what I want to do but would be very grateful if someone could point out how this is done...
for every record in qry_deliveryqueue
loop
if not fail then
send docID field to SP_sendfile
set delivereddate=getdate()
else
insert into tbl_errors (errdate,docid) values (getdate(), docid)
endif
next record
The syntax you're after is a CURSOR. The documentation has good examples that should point you in the right direction. You probably want to write a stored procedure around the logic and call that from the scheduler.
Cursors are generally inefficient, but I am assuming that your sp_sendfile has some more complex logic that precludes treating all the records as a set
You can Sql while syntax or Sql Cursor Syntax
Try this ion SQL server(This code is sample of while loop.So you have to tweak it as per your requirements)
--In sql server
Declare #idmin int,#idmax int
select #idmin=MIN(id) from qry_deliveryqueue --This is first record in qry_deliveryqueue
select #idmax=MAX(id) from qry_deliveryqueue --This is last record in qry_deliveryqueue
--You can
While(#idmin <= #idmax)
begin
IF #flag<>'Fail'
begin
-- send docID field to SP_sendfile
-- set delivereddate=getdate()
end
else
begin
insert into tbl_errors (errdate,docid) values (getdate(), docid)
end
SET #idmin=#idmin+1
end

Using temp tables in SSIS

I've created an ADO.NET connection manager, and a DataReader source with the following SQL Command:
select
'test' as testcol
INTO
#tmp
select * from #tmp
If I click the refresh button in the DataReader component, I get SqlException "Invalid object name #tmp". The SQL statment itself is clearly valid and executes properly in sql server management studio. I've also tried setting DelayValidation on the connection manager, to no avail.
is the error on the INSERT or the SELECT?
if you are issuing only one command that contains both the INSERT and SELECT, try putting a semicolon before the SELECT.
EDIT after OP comment
encapsulate all the logic within a stored procedure:
CREATE PROCEDURE YourProcedureName
AS
select
'test' as testcol
INTO
#tmp
select * from #tmp
GO
the have your application run this single SQL command:
exec YourProcedureName
EDIT after next OP comment
OP doesn't say which SQL Server version they are using, if 2005 or up, try a CTE:
;with CTEtemp as
(
select
'test' as testcol
)
select * from CTEtemp
Why couldn't this be replaced with a "SELECT 'test' as testcol"? The SSIS query parser may be having trouble with it because there's a temp table involved and it expects a single statement, not an actual SQL script. Or, if what you're sharing above is only an example for illustration, maybe something like this:
SELECT *
FROM (SELECT 'test' AS testcol)
Can you elaborate on what you're trying to accomplish here and, if it is, why the temp table is required?
Use sp_executesql
Your command would become
exec sp_executesql #statement=N'
select
''test'' as testcol
INTO
#tmp
select * from #tmp'
You must use nvarchar string (hence the N), and escape single quotes by doubling them.
I had the same problem as you and this is how I just fixed it.

Problem with SET FMTONLY ON

I'm executing stored procedures using SET FMTONLY ON, in order to emulate what our code generator does. However, it seems that the results are cached when executed like this, as I'm still getting a Conversion failed error from a proc that I have just dropped! This happens even when I execute the proc without SET FMTONLY ON.
Can anyone please tell me what's going on here?
Some statements will still be executed, even with SET FMTONLY ON. You "Conversion failed" error could be from something as simple as a set variable statement in the stored proc. For example, this returns the metadata for the first query, but throws an exception when it runs the last statement:
SET FMTONLY on
select 1 as a
declare #a int
set #a = 'a'
As for running a dropped procedure, that's a new one to me. SQL Server uses the system tables to determine the object to execute, so it doesn't matter if the execution plan is cached for that object. If you drop it, it is deleted from the system tables, and should never be executable. Could you please query sysobjects (or sys.objects) just before you execute the procedure? I expect you'll find that you haven't dropped it.
This sounds like a client-side error. Do you get the same message when running through SQL Management Studio?
Have you confirmed that there isn't another procedure with the same name that's owned by a different schema/user?
DDL statements are parsed, but ignored when run if SET FMTONLY ON has been executed on the connection. So if you drop a proc, table, etc when FMTONLY is ON, the statement is parsed, but the action is not executed.
Try this to verify
SET FMTONLY OFF
--Create table to test on
CREATE TABLE TestTable (Column1 INT, Column2 INT)
--insert 1 record
INSERT INTO TestTable (Column1, Column2)
VALUES (1,2)
--validate the record was inserted
SELECT * FROM TestTable
--now set format only to ON
SET FMTONLY ON
--columns are returned, but no data
SELECT * FROM TestTable
--perform DDL statement with FMTONLY ON
DROP TABLE TestTable
--Turn FMTONLY OFF again
SET FMTONLY OFF
--The table was dropped above, so this should not work
SELECT * FROM TestTable
DROP TABLE TestTable
SELECT * FROM TestTable

Resources