2016-05-12 35 views
0

我有一個bigint列的表,我試圖讓一個插入工作。我們遇到了無法將數據轉換爲數字並且插入失敗的問題。這主要是諸如數據中的空格或線返回的事物,即「123」,「1 365」。使用而不是觸發器來轉換數據類型

由於我無法訪問嘗試插入這些不良數據的軟件,因此我認爲創建一個而不是觸發器並使用一個函數去除所有非數字字符將解決此問題。

這是觸發器在做什麼的基本概念。

TRIGGER [dbo].[Delivery_Before_TRG] 
    ON [dbo].[Delivery] 
    instead of INSERT 
AS 
BEGIN 

    SET NOCOUNT ON; 

    INSERT INTO [dbo].[Delivery] 
      (....,[pin],....) 
    select .... 
      ,[dbo].[udf_GetNumericOnly](inserted.pin) 
      ,.... 
    from inserted; 

END 

而這是udf_GetNumberOnly函數。

FUNCTION [dbo].[udf_GetNumericOnly] 
(
    @Value varchar(500) 
) 
RETURNS bigint 
AS 

BEGIN 

    Declare 
     @Pos tinyint, 
     @Char char(1) 

    Set @Value = REPLACE(@Value, ' ', '')  -- Strip all spaces 
    Set @Pos = LEN(@Value)      -- Give some non-zero value 
    While @Pos > 0 
     Begin 
      Set @Pos = PATINDEX('%[^0-9]%', @Value) ) 
      If @Pos > 0 
       Begin 
        Set @Char = SUBSTRING(@Value, @Pos, 1)  -- Non numeric character 
        Set @Value = REPLACE(@Value, @Char, '') 
       End 
     End 

    Set @Value = RTrim(LTrim(@Value)) 

    Return convert(bigint,@Value) 

END 

我可以運行功能,它會剝奪任何東西都非數字字符,我通過它,但是,當我嘗試運行一個INSERT語句到我的表,我收到了消息8114,級別16 ,狀態5,行4 將數據類型varchar轉換爲bigint時出錯。錯誤。

從我可以告訴問題是與SQL服務器檢查,我試圖插入的字段匹配目標表列數據類型之前,我的觸發器獲取數據的轉換它轉換它。我知道這一點,因爲我修改了觸發器,直接在引腳字段中插入一個數字,仍然會出現此錯誤。

此外,我知道這不是函數失敗,因爲我可以編寫一個插入失敗,然後更改該插入調用該函數,它會工作。

--This fails 
INSERT INTO (....,pin,...) 
VALUES(....,'1a23',....) 

--This works 
INSERT INTO (....,pin,...) 
VALUES(....,udf_GetNumericOnly('1a23'),....) 
+0

您使用的是哪年版本的SQL Server? –

+0

我相信我們在SQL Server 2012上。它的版本是11.0.2100.60。 – Daniel

回答

0

是的,代碼解析器在解析器確認你寫了有效的sql之後立即查看查詢中的數據類型。 INSTEAD OF INSERT觸發器會觸發每一行將被插入的行,這是無效的轉換不會。

+0

所以我假設這意味着沒有辦法解決這個問題,我唯一的選擇是將該列的數據類型更改爲varchar,或者以某種方式使插入始終爲「可投射」。 – Daniel

+0

聽起來你不能改變應用程序,但數據上游越乾淨越好。你可以做一些醜陋的東西,比如像你提到的那樣將列更改爲varchar,並且可能每隔一段時間運行一次SQL代理作業來刪除非#字符?但真正的解決方案在源頭上。 :) –