2010-12-17 5 views
9

を使用せずに、int型にカンマ区切りの文字列に変換しトン-SQLは、私はint型のリストを渡しているユーザが作成した機能

すなわち(カンマ区切り)。 1, 2, 3, 4

私のsp。しかし、リストが文字列であるためにエラーが発生し、intフィールドと比較しています。ユーザーが作成した関数を使わずにリストをintに変換する方法はありますか?

注:社員コードは、エラーが

+0

どのバージョンのSQL Serverですか?そして、あなたのSPを呼んでいるコードを変更することができますか? –

+0

@Damien SQL Server 2005.はい私はspを呼び出すコードを変更することができます。 – Kukoy

+1

ラット。 2008年には、テーブル値のパラメータの使用に変更することをお勧めします。 –

答えて

8

このリストをintにキャストするのではなく、intのリストにキャストします。

キャスト演算子や関数はありませんが、動的SQLを使用して回避することができます。

基本的にあなたが

EXECUTE('SELECT * FROM tbl_Employee WHERE employeeID IN ('[email protected]+')') 

を書くにはかかわらず、SQLインジェクション攻撃に注意してください!

+3

これは、OPが望んでいることを実行するのに適したネイティブな方法です。従業員とIDの数が増えるにつれて、IN句はますます無効になることに注意してください。 2005年から2008年には、「存在」が好ましい。また、動的SQLをキャッシュすることもできないため、他のステートメントと同じように実行速度が向上することはありません。 – Brad

+0

@ブラッド:動的ステートメントは他のものと同様にキャッシュされます。クエリテキストを変更しない限り、キャッシュされたプランが使用されます。もちろん、クエリが非常に頻繁に実行されると、ここでは異なるIDリストが問題になります。 EXISTSは検索されたIDを格納するためにいくつかの(一時的な)テーブルを必要とします。e。ユーザーがチェックボックスを使用して特定の従業員を選択できるWebアプリケーションから)、INは依然として最良の選択肢です。 – TToni

+0

ここで 'EXISTS'は正確には実用的ではないことに同意します。テーブルまたは' IN'リストが大きい場合は、* preferred *であることを指摘したいだけでした。これは、SQLが動的SQLのキャッシュ計画を(各変更ごとに)実行することを知ることには良いことです。しかし、このキャッシングは、クエリが頻繁に変更されるため、大幅に割引になると思います。そうでない場合は、なぜ動的SQLを使用するのですか? – Brad

4
あなたがいないだけで string intに変換しようとしている

が、いくつかのint s "をintにvarchar型変換できません" であるINT

declare @intArray varchar(200) 

SELECT * 
FROM tbl_Employee 
WHERE employeeID IN (@intArray) 

ですになります。 SELECTは、配列にリストされているすべての従業員のIDとIDを返しますか?

には、この機能を使用しないとわかっています。しかし、これは私が現在行っている方法であり、うまくいきます。私の答えからあなたがするものを取りなさい。

このコードではwhileループを使用していますが、SQL 2005/2008の場合は再帰的なCTEに改善される可能性があります。関数の出力をINNER JOINのテーブルとして使用すると、非常に素早くフィルタリングすることができます。

/* 
************************************************************************************************************************ 
    Name:   ConvertDelimitedListIntoTable 
    Description: Converts a list of delimited values into a table for use like a dynamic IN statment 

    Modification History 
    Date  Author   Description 
    ========== ============ ==================================== 
    2009-01-31 B. Williams  Initial Creation 

************************************************************************************************************************ 
*/ 
ALTER FUNCTION [dbo].[ConvertDelimitedListIntoTable] (
    @list NVARCHAR(MAX) ,@delimiter CHAR(1)) 
RETURNS @table TABLE ( 
    item VARCHAR(255) NOT NULL) 
AS 
    BEGIN 
     DECLARE @pos INT ,@nextpos INT ,@valuelen INT 

     SELECT @pos = 0 ,@nextpos = 1 

     WHILE @nextpos > 0 
      BEGIN 
       SELECT @nextpos = CHARINDEX(@delimiter,@list,@pos + 1) 
       SELECT @valuelen = CASE WHEN @nextpos > 0 THEN @nextpos 
             ELSE LEN(@list) + 1 
            END - @pos - 1 
       INSERT @table (item) 
       VALUES (CONVERT(INT,SUBSTRING(@list,@pos + 1,@valuelen))) 
       SELECT @pos = @nextpos 

      END 

     DELETE FROM @table 
     WHERE item = '' 

     RETURN 
    END 

用途:

DECLARE @intArray varchar(200) 

SELECT * 
FROM tbl_Employee e 
     INNER JOIN dbo.ConvertDelimitedListIntoTable(@intArray,',') arr 
       ON e.EmployeeID = arr.Item 

tallyテーブルでこれを行う簡単な方法があるかもしれません。

+0

それは素晴らしいです、ありがとう! –

+0

ストアドプロシージャで最初のソリューションの作業を管理できませんでした。 ありがとうございました! –

関連する問題