1

我尽我所能环顾网络,但这个问题让我望而却步。我在 SSIS 中有一个可以正常工作的存储过程。它做了很多事情,最终返回了一些数字和文本。该过程本身使用 #temp 表,因为数据不需要存在于 proc 运行之外并返回约 931K 行。

下一步是将proc的输出导入excel。使用 MS 查询,我调用包含必要参数的 proc。它运行但我得到的唯一数据是带有数字的列。我缺少文本值。我认为这可能是从 SSIS 到 Excel 的文本翻译问题,所以我将输出从 nvarchar 更改为 varchar,问题仍然存在。我编写了proc,所以我可以进行任何必要的更改。另外,我认为这可能是一个临时表问题,所以我尝试构建一个表,使用 proc 在其中插入数据,然后将该表拉入 Excel,虽然我得到了更多的文本列,但数字仍然是空白的。

有什么建议吗?

问题的简短版本:SQL 在管理工作室中工作,但文本未返回到 Excel。当完成导入/更新时,proc 中的行数与 Excel 中的行数匹配。数字按预期返回。

版本:

Excel:2007 - SQL Server:2005 - Management Studio:2008R2 - 使用 MS 查询的 ODBC 连接 -

USE [cmdb]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER proc [estimate].[sp_calendar]( 
    @calendar_start char(8),
    @years as int   
    )
as

set nocount on;

declare @calendar_end char(8)
declare @actual_start_date datetime
declare @actual_end_date datetime
declare @loop_counter datetime

set @actual_start_date = CONVERT (datetime, @calendar_start, 112)
set @loop_counter = @actual_start_date
set @actual_end_date = dateadd(year,+@years,@actual_start_date)
set @calendar_end = cast(year(@actual_end_date) as char(4))+RIGHT('00'+ CONVERT(VARCHAR,month(@actual_end_date)),2)+RIGHT('00'+ CONVERT(VARCHAR,day(@actual_end_date)),2)

begin
create table #calendar (
    [yearmonth] nvarchar(8)
)
end

begin
    create table #results (
        [actual ExpectedActionDt] datetime
        ,[calc ExpectedActionDt] ntext
        ,ExpectedActionDt datetime
        ,[calc IntegratedReleasePlanDt] ntext
        ,IntegratedReleasePlanDt datetime
        ,[key] ntext
        ,projectid ntext
        ,projectnm ntext
        ,ParentChaseProjectNo ntext
        ,VersionTag ntext
        ,itemid ntext
        ,Qty float
        ,ItemNotes ntext
        ,CashflowType ntext
        ,frequency  ntext
        ,UnitPrice float
        ,[cost] float
        )
end

begin
    create table #baseline (
    [actual ExpectedActionDt] datetime
    ,[calc ExpectedActionDt] nvarchar(8)
    ,ExpectedActionDt datetime
    ,[calc IntegratedReleasePlanDt] nvarchar(8)
    ,IntegratedReleasePlanDt datetime
    ,[key] ntext
    ,projectid ntext
    ,projectnm ntext
    ,ParentChaseProjectNo ntext
    ,VersionTag ntext
    ,itemid ntext
    ,Qty float
    ,ItemNotes ntext
    ,CashflowType ntext
    ,frequency ntext
    ,UnitPrice float
    ,[cost] float)
end 

insert into #calendar (
        [yearmonth])
        select 
        distinct calendarid [yearmonth]
    from 
        [cmdb_core].[dbo].[Calendar] 
    where 
        calendarid between @calendar_start and @calendar_end

    insert into #baseline (
        [actual ExpectedActionDt]
        ,[calc ExpectedActionDt]
        ,ExpectedActionDt
        ,[calc IntegratedReleasePlanDt]
        ,IntegratedReleasePlanDt
        ,[key]
        ,projectid
        ,projectnm
        ,ParentChaseProjectNo   
        ,VersionTag
        ,itemid
        ,Qty
        ,ItemNotes
        ,CashflowType
        ,frequency
        ,UnitPrice
        ,[cost])        
    select  
        case
            when (ExpectedActionDt is not null)
                then ExpectedActionDt
            when (IntegratedReleasePlanDt is not null)
                then IntegratedReleasePlanDt
            else
                DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
        end [actual ExpectedActionDt]
        ,case
            when (ExpectedActionDt is not null)
                then cast(year(ExpectedActionDt) as char(4))+RIGHT('00000'+ CONVERT(VARCHAR,month(ExpectedActionDt)),2)+RIGHT('00'+ CONVERT(VARCHAR,day(ExpectedActionDt)),2)
            when (IntegratedReleasePlanDt is not null)
                then cast(year(IntegratedReleasePlanDt) as char(4))+RIGHT('00000'+ CONVERT(VARCHAR,month(IntegratedReleasePlanDt)),2)+RIGHT('00'+ CONVERT(VARCHAR,day(IntegratedReleasePlanDt)),2)
            else
                cast(year(getdate()) as char(4))+'0101'
        end [calc ExpectedActionDt]
        ,ExpectedActionDt
        ,cast(year(IntegratedReleasePlanDt) as char(4))+RIGHT('00'+ CONVERT(VARCHAR,month(IntegratedReleasePlanDt)),2)+RIGHT('00'+ CONVERT(VARCHAR,day(IntegratedReleasePlanDt)),2) [calc IntegratedReleasePlanDt]
        ,IntegratedReleasePlanDt
        ,cast(ModelEstimateId as nvarchar(max))+cast(BucketId as nvarchar(max))+cast(ItemNo as nvarchar(max)) [key]
        ,projectid
        ,projectnm
        ,ParentChaseProjectNo   
        ,VersionTag
        ,itemid
        ,Qty
        ,ItemNotes
        ,CashflowType
        ,frequency
        ,UnitPrice
        ,case
            when frequency = 'OneTime'
                then Qty
            else
                cast(round((UnitPrice*Qty)/12,0) as int)
            end [cost]
    from 
        estimate.ComputedEstimates
    where
        [status] <> 'Hold'
        and CostCategory <> 'Assembly'
        and includeinforecast = 'Y'
        and case
            when (ExpectedActionDt is not null)
                then cast(year(ExpectedActionDt) as char(4))+RIGHT('00000'+ CONVERT(VARCHAR,month(ExpectedActionDt)),2)+RIGHT('00'+ CONVERT(VARCHAR,day(ExpectedActionDt)),2)
            when (IntegratedReleasePlanDt is not null)
                then cast(year(IntegratedReleasePlanDt) as char(4))+RIGHT('00000'+ CONVERT(VARCHAR,month(IntegratedReleasePlanDt)),2)+RIGHT('00'+ CONVERT(VARCHAR,day(IntegratedReleasePlanDt)),2)
            else
                cast(year(getdate()) as char(4))+'0101'
            end >= @calendar_start


WHILE (@loop_counter <= @actual_end_date)
BEGIN
insert into #results (
        [actual ExpectedActionDt]
        ,[calc ExpectedActionDt]
        ,ExpectedActionDt
        ,[calc IntegratedReleasePlanDt]
        ,IntegratedReleasePlanDt
        ,[key]
        ,projectid
        ,projectnm
        ,ParentChaseProjectNo
        ,VersionTag
        ,itemid
        ,Qty
        ,ItemNotes
        ,CashflowType
        ,frequency
        ,UnitPrice
        ,[cost])
select * from #baseline where [actual ExpectedActionDt] >= @loop_counter

set @loop_counter = dateadd(day,+1,@loop_counter)
END


select 
    c.[yearmonth]
    ,a.[calc ExpectedActionDt]
    ,a.[key]
    ,a.projectid
    ,a.projectnm
    ,a.ParentChaseProjectNo 
    ,a.VersionTag
    ,a.itemid
    ,a.ItemNotes
    ,a.CashflowType
    ,a.frequency
    ,a.Qty
    ,a.UnitPrice
    ,a.[cost]
from
    #calendar as c  
    left outer join
    #results a
    on c.[yearmonth] = a.[calc ExpectedActionDt]
order by 1,2,3

drop table #baseline
drop table #results
drop table #calendar
4

2 回答 2

2

这个问题的解决方案归结为数据类型。如果您像我一样知道您的目标 Excel,那么您必须使用 Excel 可以转换的数据类型。我一直在使用没有被带到 Excel 中的 nvarchar(max),当我将字段更改为文本和字符时,我很好。一旦我知道要寻找什么,我就从 Microsoft 找到了这个答案:Microsoft Excel 数据类型。还有一个关于限制的页面:数据类型限制。另一部分是我使用的是存储过程而不是纯 SQL,尽管直接从表中选择也存在问题。我试图加载一个表,而不是依赖具有类似故障的存储过程。没有任何错误返回,只是没有数据。通过我的测试,以下是文本/字符类型转换及其成功:

text - 工作
ntext - 工作
char - 工作
nchar - 工作
varchar - 失败
nvarchar - 失败

于 2013-03-13T12:36:42.713 回答
0

我猜该过程会从#results 中进行最终选择,并且在 SQL Server 管理工作室查询分析器中可以看到所需的结果;但是,当您在 SSIS 数据流中调用该过程时,文本数据会在进入 Excel 目标的途中消失吗?

这里有几件事可以尝试。使用数据查看器(位于步骤之间的箭头上)检查您的文本列是否包含过程调用下游的所需文本。使用派生列小部件将文本放入所需的数据类型(例如,VARCHAR 的代码页 1252)。SSIS 对数据类型很挑剔。

最后,尝试不同的目标,例如 csv 文件等纯文本文件。您可以使用派生列小部件进行连接并在文本周围添加逗号和双引号以及您想尝试的任何其他内容。然后您可以在记事本中查看是否获得了所需的输出,并且 Excel 应该能够打开一个 csv 文件。

Excel 记录曾经有 64,000 条限制,但我相信这在 Excel 2007 中早已不复存在。我不断达到 2000KB 的限制,将输出剪切并粘贴到记事本中(它默默地失败了,这令人沮丧,直到我记得为止)。但是您的 931K 记录可能会达到其他限制,因此请尝试较小的输出集,看看它们的工作方式是否有所不同。

于 2013-03-12T18:12:46.503 回答