将@Output表结果发送到SSIS包中返回0行的平面文件

时间:2016-04-26 14:42:11

标签: sql-server ssis

嗨,谢谢你的帮助。

我有一个SSIS包,其第一步执行sql delete查询以删除表中的行,并将删除的行发送到@output表。下一步尝试获取@output表并将其发送到平面文件目标。当我在sql server mgmt中运行删除查询时。 studio它成功输出它删除的行但由于某种原因,包中的平面文件最终为0行。我需要做些什么才能在后续的平面文件目标组件中访问@output表数据?我需要创建临时表吗?

以下是在@output表中输出已删除行的查询。我想把@output表的内容发送到平面文件目的地。

DECLARE @Output table
(PatientVisitID         INT`
,VisitNumber            NVARCHAR(45)`
,LastName               NVARCHAR(45)`
,FirstName              NVARCHAR(45)`
,MiddleName             NVARCHAR(45)`
,NamePrefix             NVARCHAR(45)`
,NameSuffix             NVARCHAR(45)`
,BirthDate              NVARCHAR(45)
,MedicalRecordNumber    NVARCHAR(45)
,Gender                 NVARCHAR(1)
,AdmitState             NVARCHAR(45)
,AdmitDateTime          NVARCHAR(45)
,DischargeDateTime      NVARCHAR(45)
,SSN                    NVARCHAR(12)
,PatientType            NVARCHAR(45)
,HospitalService        NVARCHAR(45)
,Location               NVARCHAR(45)
,DischargeDisposition   NVARCHAR(45)
)
DELETE 
FROM PatientVisits
OUTPUT 
DELETED.PatientVisitID 
,DELETED.VisitNumber            
,DELETED.LastName               
,DELETED.FirstName              
,DELETED.MiddleName             
,DELETED.NamePrefix             
,DELETED.NameSuffix             
,DELETED.BirthDate              
,DELETED.MedicalRecordNumber    
,DELETED.Gender                 
,DELETED.AdmitState             
,DELETED.AdmitDateTime          
,DELETED.DischargeDateTime      
,DELETED.SSN                    
,DELETED.PatientType            
,DELETED.HospitalService        
,DELETED.Location               
,DELETED.DischargeDisposition   
INTO @Output
where 
CURRENT_TIMESTAMP - 33  > cast(convert(varchar,AdmitDateTime,101) as   DATETIME)
AND PatientType NOT IN ('01','12')
SELECT * FROM @Output`

3 个答案:

答案 0 :(得分:0)

您可以尝试使用临时表 -

将此语句放在执行SQL任务中,并将连接管理器的 RetainSameConnection设置为' True' (这将确保临时表在另一项任务)

IF OBJECT_ID('tempdb..##DeletedRows') IS NOT NULL
DROP TABLE ##DeletedRows
CREATE TABLE ##DeletedRows(EmpId TINYINT, EmpName VARCHAR(10))

  DELETE 
  FROM dbo.Emp
  OUTPUT
  DELETED.EmpId,
  DELETED.EmpName
  INTO ##DeletedRows

接下来,使用数据流任务并将数据流任务的延迟验证属性设置为True 。删除OLE DB源任务和平面文件目标。

第一次,在db

中运行此语句
CREATE TABLE ##DeletedRows(EmpId TINYINT, EmpName VARCHAR(10))

在OLE DB Source中,使用sql语句

SELECT * FROM ##DeletedRows

并将列映射到Flat文件。由于我们希望最初将列从OLE DB源映射到平面文件,因此我们在db中创建了临时表。由于延迟验证设置为True,因此从下次开始我们不需要手动创建临时表。

enter image description here

答案 1 :(得分:0)

您的数据和/或查询存在问题。

考虑以下简化演示

IF NOT EXISTS

(
    SELECT
        *
    FROM
        sys.schemas AS S
        INNER JOIN sys.tables AS T
        ON S.schema_id = T.schema_id
    WHERE 
        S.name = 'dbo'
        AND T.name = 'so_36868244'
)
BEGIN
    CREATE TABLE dbo.so_36868244
    (
        SSN nvarchar(12) NOT NULL
    );
END

INSERT INTO
    dbo.so_36868244
(
    SSN
)
SELECT
    D.SSN
FROM
(
    VALUES
        (N'111-22-3333')
    ,   (N'222-33-4444')
    ,   (N'222-33-4445')
    ,   (N'222-33-4446')
) D(SSN)
LEFT OUTER JOIN
    dbo.so_36868244 AS S
    ON S.SSN = D.SSN
WHERE
    S.SSN IS NULL;

我们现在有一个包含单列和5行数据的表。

我使用了以下查询,该查询使用OUTPUT子句将DELETED数据推送到表变量中,然后从中进行选择

DECLARE
    @output table
(
    SSN nvarchar(12) NOT NULL
);

DELETE TOP (2) S
OUTPUT
    Deleted.SSN
INTO
    @output ( SSN )
FROM
    dbo.so_36868244 AS S

SELECT O.SSN FROM @output AS O;

运行3次,最终会有2行,2行,没有行。没问题,重新运行第一个查询,再次有4行 - 对幂等操作很有帮助。

我使用该查询作为OLE DB源的源,然后将数据写入平面文件。

Works fine

生殖

商业智能标记语言Biml允许我使用简化的XML方言来描述SSIS包。以下Biml在通过Biml引擎提供时,将被转换为SSIS包,用于您正在使用的任何版本的SQL Server。

听起来不错?抓住BimlExpress,它是免费的,并为您的SSIS版本安装它。

安装完成后,在BimlExpress菜单下选择"添加新Biml文件"。粘贴以下

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <OleDbConnection Name="tempdb" ConnectionString="Data Source=localhost\dev2014;Initial Catalog=tempdb;Provider=SQLNCLI11.0;Integrated Security=SSPI;"/>
        <FlatFileConnection FilePath="C:\ssisdata\so\output\so_36868244.txt" FileFormat="FFF so_36868244" Name="FFCM" />
    </Connections>
    <FileFormats>
        <FlatFileFormat Name="FFF so_36868244" IsUnicode="false" ColumnNamesInFirstDataRow="true" FlatFileType="Delimited">
            <Columns>
                <Column Name="SSN" DataType="String" Length="12" Delimiter="CRLF" />
            </Columns>
        </FlatFileFormat>
    </FileFormats>
    <Packages>
        <Package Name="so_36868244">
            <Tasks>
                <Dataflow Name="DFT Stuff">
                    <Transformations>
                        <OleDbSource ConnectionName="tempdb" Name="SQL Stuff">
                            <DirectInput><![CDATA[DECLARE
    @output table
(
    SSN nvarchar(12) NOT NULL
);

DELETE TOP (2) S
OUTPUT
    Deleted.SSN
INTO
    @output ( SSN )
FROM
    dbo.so_36868244 AS S

SELECT O.SSN FROM @output AS O;]]></DirectInput>
                        </OleDbSource>
                        <DerivedColumns Name="DER Placeholder"></DerivedColumns>
                        <FlatFileDestination ConnectionName="FFCM" Name="FFDST Extract" Overwrite="true" />
                    </Transformations>
                </Dataflow>
            </Tasks>            
        </Package>
    </Packages>
</Biml>

将第3行和第4行编辑为有效的数据库连接字符串(我在DEV2014的命名实例上使用tempdb)以及指向磁盘上的有效路径(我的使用C:\ ssisdata \ so \ output)< / p>

右键单击bimlscript.biml文件,弹出一个名为so_36868244的软件包,该软件包应能立即运行并生成包含

等内容的平面文件
SSN
111-22-3333
222-33-4444

你的例子

有什么问题

如果无法访问您的系统和/或示例数据,那么非常很难说。

我会给你不请自来的建议,虽然这会改善你的发展事业。你应该避免像CURRENT_TIMESTAMP - 33这样的速记符号。与DATEADD(DAY, -33, CURRENT_TIMESTAMP)

相比,它不清楚结果会是什么,并且可以节省可忽略不计的击键次数

cast(convert(varchar,AdmitDateTime,101) as DATETIME)还有更多优雅的机制来删除日期的时间部分。

答案 2 :(得分:-1)

您需要将其设为真实(永久)表格。在一个执行SQL任务中创建的表变量和临时表在其他执行SQL任务中不可用。

完成后,您可以随时删除永久表。