2012-04-10 66 views
0

們都面臨着在SQL Server字符串長度控制一個很大的問題問題2008SQL服務器:與字段長度控制

我們系統的簡要回顧:

  • 在持久性臨時區域進口數據從*.txt文件(分號作爲分隔符),在SQL Server環境中使用批量插入;
  • 在PSA表中所有列都是varchar(MAX);
  • 使用插入語句進行清理操作,基於帶有多條條件的select。

我們處理的問題是單列類型和長度,事實上在數據倉庫級別它必須是數字,其長度不能超過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,它們不是數字,而第一個重疊最大尺寸。

至於結果,insert語句也給後面

串o二進制數據將被截斷

錯誤和失敗的插入。

在此先感謝!我期待你的幫助!

恩里科

回答

0

你試過執行該查詢,並添加codice_ean_prodotto = 'NE20000003039' WHERE子句?確保這些是給你問題的實際領域。如果select使用where子句返回一行,那麼邏輯上出現了錯誤。

我傾向於在EXISTS子查詢中的having COUNT (*) = 1子句 - 是否有可能爲這些特定的鍵有多個記錄?只要你的PK由4個字段(data_giacenza, codice_articolo_socio, codice_socio, codice_gln)組成,你就不需要GROUP BY和HAVING子句。如果你沒有加入你的主鍵,那可能是它的罪魁禍首。

但是,很難說沒有看到您的數據模型。

0

我想通了什麼是錯的。 在內部選擇中,我們從選擇中排除了所有不尊重格式約束和重複的記錄(count(*)=1的含義),僅提取目標表的PK。 但是,當用PK選擇時,我們也檢索那些重複的記錄,但是被格式約束排除,導致插入由於維度問題而出錯。

現在我分了步驟:

  1. 重複查找和刪除
  2. 選擇與格式限制

它的工作原理!