基于第一行中的值插入

时间:2015-10-29 18:33:19

标签: tsql sql-server-2005

我有一个固定文件,我将其导入一个列,其数据类似于您在下面看到的数据:

ABC$        WC        11683                                    
11608000163118430001002010056788000000007680031722800315723      
11683000486080280000002010043213000000007120012669100126691      
ABC$        WC                         000000020000000148000     
ABC$        WC        11683                                    
1168101057561604000050200001234000000027020023194001231940      
54322010240519720000502000011682000000035640006721001067210      
1167701030336257000050200008765000000023610029066101151149      
11680010471244820000502000011680000000027515026398201263982

我想拆分并将这些数据插入到另一个表中,但我想这样做,只要'11683'等于另一个表+ 1中的列值。然后我将增加该值(此处未显示) )。

我尝试了以下内容:

declare @blob as varchar(5) 
declare @Num as varchar(5)

set @blob = substring(sdg_winn_blob.blob, 23,5)
set @Num = (Cnum.num + 1)

IF @blob = @Num
INSERT INTO SDG_CWF
    (
        GAME,SERIAL,WINNER,TYPE
    )
SELECT convert(numeric, substring(blob,28, 5)),convert(numeric, substring(blob, 8, 9)),
        (Case when (substring(blob, 6,2)='10') then '3' 
              when (substring(blob, 6,2)='11') then '4' 
              else substring(blob, 7, 1)
         End),
        (Case when (substring(blob, 52,2)='10') then '3' 
              when (substring(blob, 52,2)='11') then '4' 
              else substring(blob, 53, 1)
         End)

FROM sdg_winn_blob
WHERE blob not like 'ABC$%'
else
print 'The Job Failed'

插入工作正常,直到我尝试检查位置(23,5)处的数字是否与Cnum表中的数字相同。我收到错误:

Msg 4104, Level 16, State 1, Line 4
The multi-part identifier "sdg_winn_blob.blob" could not be bound.
Msg 4104, Level 16, State 1, Line 5
The multi-part identifier "Cnum.num" could not be bound.

1 个答案:

答案 0 :(得分:0)

看起来你可能习惯于一种程序化的,面向对象的编码风格。 SQL Server希望你的思维方式完全不同......

这一行:

set @blob = substring(sdg_winn_blob.blob, 23,5)

失败是因为SQL单独解释它。在这一行中,您没有告诉SQL对象sdg_winn_blob是什么,也没有告诉其成员blob

由于这些是数据库表/列,因此它们只能作为包含FROM子句的查询的一部分进行访问。这是FROM告诉SQL这些东西在哪里。

因此,您需要使用以下内容替换该行(以及下一行):

Select @blob = substring(sdg_winn_blob.blob, 23,5)
From sdg_winn_blob
Where... 

此外,据我所知,你的整个方法在概念上是迭代的:你在依次查看每一条线,处理它,然后转移到下一条线方面考虑这个问题。 SQL确实提供了这方面的工具(你在这里没有使用过),但它们很少是最好的解决方案。 SQL更喜欢(并针对基于集合的方法进行优化):设计一次性对所有行进行操作的查询。

目前我认为你的查询不会做你想要的,因为你期望SQL不遵循的迭代行为。

如果你想“像SQL Server一样思考”,你需要处理这个问题的方法是构造(仅使用SELECT类型查询)一组行,这些行具有来自标题行的'11683'类型值,应用于每个行要插入SDG_CWF的相应“数据”行。

然后,您可以使用SQL JOIN将此行集链接到Cnum表,并确定每行是否符合Cnum中所需的条件。然后可以将这组行插入SDG_CWF。没有涉及变量或IF语句(它们在SQL中的必要性远远低于某些人的想法)。

有多种可能的方法,其中没有一种非常简单(除非我遗漏了一些明显的东西)。所有这些都需要你将你的逻辑分解为几个步骤,获取你的初始数据集(只是一个blob列)并将其变成更接近你需要的东西,然后重复。您可能希望自己解决这个问题,但如果没有,我会在this SQLFiddle中列出一个示例。

我并不认为这个例子是最快或最好的(事实并非如此),但希望它能说明我想要思考SQL想要你的方式的意思。该网站背后的SQL引擎使用的是SQL 2008,但我提供的解决方案应该在2005年同样有效。如果您可以访问2012或更高版本,则可以采用更快捷的方式。