2016-05-12 10 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 Serverのチェックと関係があるからです。ピンフィールドに数字を直接挿入するようにトリガを変更したため、このエラーが発生するため、これはわかっています。

また、関数が失敗するのは、挿入に失敗して関数を呼び出すためにその挿入を変更できるためです。

--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

うん、algebrizerは、パーサは、有効なSQLを書いて確認します右の後に、クエリ内のデータ型を調べます。 INSTEAD OF INSERTトリガーは、挿入される行ごとに起動します。無効なキャストは挿入されません。

+0

だから私はこれが周りには方法がないと仮定していると私の唯一のオプションは、その列のデータ型をvarcharに変更するか、何らかの形でインサートを常に "キャスト可能"にすることです。 – Daniel

+0

アプリケーションを変更できないように聞こえますが、データがより上流にあるほどクリーンです。あなたは言及しているようにvarcharに列を変更するようないくつかの醜いものを行うことができますし、SQLエージェントのジョブを1度頻繁に実行して、非#文字を削除することがありますか?しかし、実際の解決策はソースにあります。 :) –

関連する問題