0

在 SQL Server 2008 中,我们面临着字符串长度控制的大问题。

简要回顾一下我们的系统:

  • 在 SQL Server 环境中使用批量插入从文件中导入持久暂存区中的*.txt数据(分号作为分隔符);
  • 在 PSA 表中,所有列都是varchar(MAX);
  • 使用基于具有多个 where 条件的 select 的 insert 语句清理操作。

我们处理的问题是单列类型和长度,实际上在数据仓库级别它必须是数字,并且它的长度不能超过 13 位。

选择如下:

select cast(LTRIM(RTRIM(data_giacenza)) as numeric), 
                        LTRIM(RTRIM(codice_socio)), 
                        LTRIM(RTRIM(codice_gln)), 
                        LTRIM(RTRIM(tipo_gln)), 
                        LTRIM(RTRIM(codice_articolo_socio)), 
                        LTRIM(RTRIM(codice_ean_prodotto)), 
                        LTRIM(RTRIM(codice_ecat_prodotto)), 
                        LTRIM(RTRIM(famiglia)), 
                        LTRIM(RTRIM(marca)),
                        LTRIM(RTRIM(classificazione_liv_1)), 
                        LTRIM(RTRIM(classificazione_liv_2)),
                        LTRIM(RTRIM(classificazione_liv_3)), 
                        LTRIM(RTRIM(classificazione_liv_4)), 
                        LTRIM(RTRIM(modello)), 
                        LTRIM(RTRIM(descrizione_articolo)), 
                        cast(LTRIM(RTRIM(giacenza)) as numeric),
                        cast(LTRIM(RTRIM(acquistato)) as numeric), 'X' FROM psa_stock a
                          where EXISTS 
                          ( 
                          SELECT 0 
                          FROM(
                                SELECT 
                                            data_giacenza
                                           ,codice_socio
                                                 ,codice_gln
                                                 ,codice_articolo_socio
                                                 FROM psa_stock 
            where
                        LEN(LTRIM(RTRIM(data_giacenza))) = 8 and LEN(LTRIM(RTRIM(codice_socio))) = 3
                  and LEN(LTRIM(RTRIM(codice_gln))) = 13 and LEN(LTRIM(RTRIM(tipo_gln))) = 3 
                  and LEN(LTRIM(RTRIM(codice_articolo_socio))) <= 15 
                  and (LEN(LTRIM(RTRIM(codice_ean_prodotto))) <= 13 or LEN(ISNULL(codice_ean_prodotto, '')) = 0) 
                  and (LEN(LTRIM(RTRIM(codice_ecat_prodotto))) = 9 or LEN(ISNULL(codice_ecat_prodotto, '')) = 0)
                  and LEN(LTRIM(RTRIM(famiglia))) = 2
                  and (LEN(LTRIM(RTRIM(marca))) <= 20 or LEN(ISNULL(marca, '')) = 0)
                  and (LEN(LTRIM(RTRIM(modello))) <= 30 or LEN(ISNULL(modello, '')) = 0)
                  and (LEN(LTRIM(RTRIM(descrizione_articolo))) <= 50 or LEN(ISNULL(descrizione_articolo, '')) = 0)
                  and LEN(LTRIM(RTRIM(giacenza))) <= 5
                  and LEN(LTRIM(RTRIM(acquistato))) <= 5 
                  and (LEN(LTRIM(RTRIM(classificazione_liv_1))) <= 15 or LEN(ISNULL(classificazione_liv_1, '')) = 0)
                  and (LEN(LTRIM(RTRIM(classificazione_liv_2))) <= 15 or LEN(ISNULL(classificazione_liv_2, '')) = 0)
                  and (LEN(LTRIM(RTRIM(classificazione_liv_3))) <= 15 or LEN(ISNULL(classificazione_liv_3, '')) = 0)
                  and (LEN(LTRIM(RTRIM(classificazione_liv_4))) <= 15 or LEN(ISNULL(classificazione_liv_4, '')) = 0)
                  and ISNUMERIC(ltrim(rtrim(REPLACE(data_giacenza, ' ', '')))) = 1 
                  and ISNUMERIC(ltrim(rtrim(REPLACE(codice_gln, ' ', '')))) = 1 
                  and ISNUMERIC(LTRIM(RTRIM(REPLACE(giacenza, ' ', '')))) = 1 and charindex(',', giacenza) = 0
                  and ISNUMERIC(LTRIM(RTRIM(REPLACE(acquistato, ' ', '')))) = 1 
                  and ISNUMERIC(ltrim(rtrim(REPLACE(codice_ean_prodotto, ' ', '')))) = 1
                  and ISNUMERIC(ltrim(rtrim(REPLACE(codice_ecat_prodotto, ' ', '')))) = 1
                  and codice_socio in (select codice_socio from ana_socio)
                  and tipo_gln in (select tipo from ana_gln)
                  and codice_gln in (select codice_gln from dw_key_gln)
                  group by 
               data_giacenza
              ,codice_socio
                  ,codice_gln
                  ,codice_articolo_socio
                             having COUNT (*) = 1
                  ) b
          where 
                a.data_giacenza = b.data_giacenza and
                a.codice_articolo_socio = b.codice_articolo_socio and
                    a.codice_socio = b.codice_socio and
                    a.codice_gln = b.codice_gln)

临界场是codice_ean_prodotto

事实上,它还允许考虑SEAGAT7636490026751,NE20000003039,NE20000002168不是数字的值,并且首先,重叠最大维度。

结果,插入语句返回

字符串 o 二进制数据将被截断

错误并且插入失败。

提前致谢!我期待你的帮助!!!

恩里科

4

2 回答 2

0

您是否尝试过执行该查询并添加codice_ean_prodotto = 'NE20000003039'到 where 子句?确保这些是给您带来问题的实际字段。如果 select 返回带有该 where 子句的行,则说明逻辑有问题。

我倾向于having COUNT (*) = 1在 EXISTS 子查询中使用您的子句 - 这些特定键是否可能有多个记录?只要您的 PK 由这 4 个字段组成(data_giacenza, codice_articolo_socio, codice_socio, codice_gln),您就根本不需要 GROUP BY 和 HAVING 子句。如果您没有加入主键,则可能是罪魁祸首。

但是,如果不查看您的数据模型,就很难判断。

于 2012-04-17T19:41:48.330 回答
0

我发现出了什么问题。在内部选择中,我们从选择中排除所有不考虑格式约束和重复(的含义count(*)=1)的记录,仅提取目标表的 PK。但是当使用 PK 选择时,我们还会检索那些重复的记录,但被格式约束排除在外,导致插入由于尺寸问题而出错。

现在我划分了步骤:

  1. 重复查找和删除
  2. 具有格式约束的选择

有用!

于 2012-04-18T14:49:33.040 回答