sql >> データベース >  >> RDS >> Sqlserver

master..spt_valuesを使用して列を分割する理由(および方法)

    目的

    文書化されていないmaster..spt-valuesを使用する理由

    Sybase、したがってそのろくでなしの息子MS SQLは、システムプロシージャに実装される製品のさまざまな機能を提供します(サービスとして開始されるsqlserverのようなバイナリとは対照的です)。これらのシステムプロシージャプロシージャはSQLコードで記述され、sp_%.という名前が付けられています。 一部の秘密の内部構造を除いて、他のSQLコードと同じ制限とニーズがあります。これらはSybaseASEまたはSQLServer製品の一部です。そのため、必須ではありません。 それを文書化する。また、内部ビットを「文書化されていない」と合理的にラベル付けすることはできません。

    master..spt_values さまざまなレポートを作成するために、前述のシステムプロシージャがSQLテーブルに必要とするさまざまな要素がすべて含まれています。 sp システム手順を意味します。 spt システム手順のテーブルを意味します。そしてもちろんvalues はコンテンツです。

    ルックアップテーブル

    Type ='P'(の意味)とは

    人々はしばしばspt_valuesを説明します 「非正規化」として、しかしそれは間違った用語です。正しい用語は折りたたまれています 、またはパック 。これは26ほどの論理ルックアップテーブルであり、それぞれが美しく正規化され、Typeを使用して1つの物理テーブルに折りたたまれています。 論理テーブルを区別するための列。

    現在、通常のデータベースでは、それは重大なエラーになります(「1つまたは複数のルックアップテーブル」の答えを見てください)。ただし、サーバーカタログでは、26個の物理テーブルを置き換えることが望ましいです。

    • 「L」はLockTypeルックアップを表します。 「V」はDeviceTypeルックアップを表します(Vはサーバー全体のDeviceの略です)。タイプ「P2」には、INTにパックされるビットを拡張するためのビット単位の序数が含まれています。

    • 多くのシステムプロシージャが実行する必要のある射影を実行するには、SQLテーブルの形式で使用できる既知の範囲内の連続した数値のセットが必要です。タイプ「P」は、0から2047までの連続した番号のリストです。

    • プロジェクションという用語 ここでは、技術的に正確な意味、自然な論理的意味として使用されており、不自然な関係代数の意味ではありません。

    したがって、spt_values,の目的は1つだけです。 26個の折りたたまれた、そうでなければ別々の参照テーブルと1つの投影テーブルを含めるため。

    拡張

    spt_values,の通常の使用 次に、通常のルックアップまたはリファレンス、またはENUM テーブル。まず、ルックアップ値:

        SELECT *                    -- list Genders
            FROM Gender 
    

    これは、Personが拡張する必要のあるGenderCodeを持っているのと同じ方法で使用されます(非常に拡張された、これらの気紛れな日々):

        SELECT  P.*,                -- list Person
                G.Name              -- expand GenderCode to Name
            FROM Person P
            JOIN Gender G
                ON P.GenderCode = G.GenderCode
    

    例えば。 sp_lock アクティブなロックのレポートを生成し、ロックタイプを文字列名前として表示します 。ただし、master..syslocks 番号としてロックタイプが含まれています 、これらの名前は含まれていません;もしそうなら、それはひどく非正規化されたテーブルになるでしょう!クエリを実行する場合(Sybase ASEコード、変換する必要があります):

        SELECT *                    -- list LockTypes
            FROM master..spt_values 
            WHERE type = "L"
    

    66個のLockType番号に気付くでしょう および名前 ルックアップテーブルで。これにより、sp_lockが可能になります 上記のPerson::Genderのような単純なコードを実行するには:

        SELECT  spid,               -- list Active Locks
                DB_NAME(dbid),
                OBJECT_NAME(id, dbid),
                v.name,             -- expand lock name
                page,
                row
        FROM master..syslocks   L,
             master..spt_values LT
        WHERE L.type = LT.number    -- 
        AND   type = "L"            -- LockType Lookup table
        ORDER by 1, 2, 3, 4, 5, 6   -- such that perusal is easy
    

    プロジェクション

    Type ='P'(の意味)とは何ですか?

    プロジェクションとは何ですか?どのように使用されますか?

    たとえば、上記のクエリによって生成されたアクティブなロックの代わりに、すべてのリストが必要だとします。 66 LockTypes、アクティブなロック(またはNull)の数を示します。カーソルやWHILEは必要ありません ループ。 プロジェクト LockTypeルックアップテーブル、から アクティブなロックの数:

        SELECT  LT.name,            -- list LockTypes
                [Count] = (         -- with count
            SELECT COUNT(*)
                FROM master..syslocks
                WHERE type = LT.number
                    )
            FROM master..spt_values LT
            WHERE type = "L"
    

    いくつかの方法がありますが、それは1つだけです。別の方法は、サブクエリの代わりに派生テーブルを使用することです。ただし、それでもプロジェクションが必要です。

    これは通常、spt_values,が行うものです。 拡張または投影のいずれかに使用されます。そこにあることがわかったので、それを使用することもできます。安全です(master データベース)であり、事実上すべてのシステムプロシージャで使用されます。つまり、システムプロシージャはデータベースなしでは実行できません。

    列を分割するためですか?

    ああ、あなたは「1つのCSV列を複数の行に分割する」コードを理解していません。

    • spt_values,を忘れる しばらくの間、そのコードをもう一度調べてください。連続番号のリストが必要なだけなので、inはCSV列の値のリストをバイトごとにステップスルーできます。コードは、コンマまたは文字列の終わりであるバイトごとにのみアクティブ化されます。

    • 最初から作成して挿入するのではなく、SQLテーブルの形式で連続した数値のセットを取得する場所はどこですか?なぜ、master..spt_values もちろん。あなたがそれがそこにあることを知っているなら。

    • (システムストアドプロシージャのコードを読むだけで、ASEまたはSQL Serverの内部について少し学ぶことができます。)

    • 1つの列のCSVフィールドは、全体的な正規化エラーであり、2NF(繰り返し値を含む)と1NF(アトミックではない)を壊すことに注意してください。パックまたは折りたたまれていないことに注意してください。これは繰り返しグループであり、正規化されていません。このような重大なエラーの多くの悪影響の1つは、単純なSQLを使用して繰り返しグループを行としてナビゲートする代わりに、複雑なコードを使用して、正規化されていないCSVフィールドのコンテンツを判別および抽出する必要があることです。ここでspt_values P その複雑なコードのベクトルを提供し、それを容易にします。

    そのメリットは何ですか?

    私はそれに答えたと思います。持っていなかった場合、番号のリストを必要とするすべてのシステムプロシージャは、一時テーブルを作成する必要があります。それに行を挿入します。コードを実行する前に。もちろん、これらの手順を実行する必要がないため、システム手順がはるかに高速になります。

    さて、あなたがプロジェクションを実行する必要があるとき、例えば。将来のカレンダーの日付など、spt_values,を使用できます 、毎回独自の一時テーブルを作成する(または独自のプライベート永続テーブルを作成して維持する)代わりに。



    1. MariaDBの数値にパーセント記号を追加する

    2. QUERYパケットの送信中にエラーが発生しました

    3. Postgres-行を列に転置

    4. 区切り文字を使用したMySQL部分文字列の抽出