0

現在、user_type 列を持つテーブルがあり、ユーザーがその user_type に一致する場合にのみ行を表示します。データを複製したり、別のテーブルを作成したりせずに、複数の user_types を設定できるようにしたいと考えています。列を int から varchar に変換して、ユーザー タイプ ID のコンマ区切りのリストにすることができると考えました。

これまでのところ、うまく機能しています。それは、ユーザーに表示する必要があるかどうかを確認するときにそれを具体的に使用できるため、事前に user_type が何であるかを知っている限りです。

SELECT *
FROM perm
WHERE user_type='50'
    OR user_type LIKE '50,%'
    OR user_type LIKE '%,50,%'
    OR user_type LIKE '%,50'

値でテーブルを結合しようとすると、問題が発生します。私が使ってみたときIN

SELECT p.*
FROM perm p
JOIN [user] u ON u.type IN (p.user_type)

私はエラーを受け取ります:それで、私は上記で使用していた方法Conversion failed when converting the varchar value '50,40,30' to data type int.に戻ることにしました:LIKE

SELECT p.*
FROM perm p
JOIN [user] u ON (
    u.type LIKE p.user_type
    OR u.type LIKE (p.user_type + ',%')
    OR u.type LIKE ('%,' + p.user_type + ',%')
    OR u.type LIKE ('%,' + p.user_type)
)

これは、1 つのユーザー タイプ値のみを持つ結果のみを返します。INコマンドで使用するカンマ区切りのリストを変換する方法はありますか? または、動的なLIKE引数を作成する方法はありますか?

4

3 に答える 3

0

あなたが今持っているもの(恐ろしい)で動作する方法と、それを行う正しい方法(@paqogomezが提案したように)を提供します。この方法には悪用が含まPARSENAMEれ、SQL Server でのみ機能し、perm.user_type のユーザー タイプが 4 つ以下の場合にのみ機能します。4 という制限がない別の方法があります。これには、SQL Server の XML 解析の悪用が含まれますが、より複雑で時間がかかるため、ここでは説明しません。

また、特定のユーザーの Perm の行をリストしたいだけで、[user]テーブルにはid主キーがあると仮定します。

SELECT p.*
FROM [user] u
JOIN perm p ON u.type IN (
    CAST((PARSENAME(REPLACE(p.user_type,',','.'),1)) AS INT),
    CAST((PARSENAME(REPLACE(p.user_type,',','.'),2)) AS INT),
    CAST((PARSENAME(REPLACE(p.user_type,',','.'),3)) AS INT),
    CAST((PARSENAME(REPLACE(p.user_type,',','.'),4)) AS INT)
)
WHERE u.id = ?

より良い方法は、関係テーブルを使用して Perm のユーザー タイプを格納する paqogomez の方法です (Perm の主キーは次のように仮定しますid

Perm_User_Type
  Perm_id -> Perm.id
  User_type -> [user].type

次に、はるかに効率的なクエリは次のようになります。

SELECT p.*
FROM [user] u
JOIN Perm_User_Type put ON u.type = put.User_type
JOIN perm p ON put.Perm_id = p.id
WHERE u.id = ?

もちろん、この場合、ユーザー タイプの数に制限はありません。

于 2014-05-23T22:01:47.400 に答える
-1

動的 SQL なしでこれを行うことはできないと思います。何かのようなもの:

declare @sql nvarchar(max)

set @sql = '
SELECT p.*
FROM perm p
JOIN [user] u ON u.type IN (''' + p.user_type + ''')'

exec sp_ExecuteSql @sql
于 2014-05-23T21:29:56.550 に答える