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

ストアド プロシージャ 複数の行を挿入する

    テーブル値パラメータ データセットから入力できます。SQL Server に渡すときに何かばかげたことをしないと仮定すると、アトミック操作として扱われます。

    IF EXISTS
    (
        SELECT
            *
        FROM
            sys.types T
        WHERE
            T.name = 'CONTRIVED_EXAMPLE'
    )
    BEGIN
        PRINT 'Dropping type dbo.CONTRIVED_EXAMPLE'
        DROP TYPE dbo.CONTRIVED_EXAMPLE
    END
    PRINT 'Creating type dbo.CONTRIVED_EXAMPLE'
    GO
    -----------------------------------------------------------------------------
    -- Type: dbo.CONTRIVED_EXAMPLE
    -- Author: Bill Fellows
    -- Date: 2010-06-07
    --
    -- This is a user-defined table type demonstrating the syntax
    -- for a table valued parameter
    --
    -- See also:
    --
    -- Modified:
    --
    -----------------------------------------------------------------------------
    CREATE TYPE
        dbo.CONTRIVED_EXAMPLE AS TABLE
    (
         twitter_handle varchar(15) NOT NULL
    ,    have_met bit NOT NULL
    )
    GO
    
    IF EXISTS
    (
        SELECT
            *
        FROM
            sys.tables T
        WHERE
            T.name = 'CONTRIVED_EXAMPLE_TABLE'
    )
    BEGIN
        PRINT 'Dropping type dbo.CONTRIVED_EXAMPLE_TABLE'
        DROP TABLE dbo.CONTRIVED_EXAMPLE_TABLE
    END
    PRINT 'Creating table dbo.CONTRIVED_EXAMPLE_TABLE'
    GO
    -----------------------------------------------------------------------------
    -- Type: dbo.CONTRIVED_EXAMPLE_TABLE
    -- Author: Bill Fellows
    -- Date: 2010-06-07
    --
    -- This is a boring table demonstrating the syntax
    -- for a table valued parameter
    --
    -- See also:
    --
    -- Modified:
    --
    -----------------------------------------------------------------------------
    CREATE TABLE
        dbo.CONTRIVED_EXAMPLE_TABLE 
    (
        row_id int identity(1,10) NOT NULL PRIMARY KEY
    ,    twitter_handle varchar(15) NOT NULL
    ,    have_met bit NOT NULL
    )
    GO
    
    IF EXISTS
    (
        SELECT
            SO.*
        FROM
            dbo.sysobjects SO
        WHERE
            SO.id = OBJECT_ID('dbo.EchoBack')
            AND OBJECTPROPERTY(SO.id, 'IsProcedure') = 1
    )
    BEGIN
        PRINT 'Dropping stored procedure dbo.EchoBack'
        DROP PROCEDURE dbo.EchoBack
    END
    GO
    PRINT 'Creating stored procedure dbo.EchoBack'
    GO
    -----------------------------------------------------------------------------
    -- Function: dbo.EchoBack
    -- Author: Bill Fellows
    -- Date: 2010-06-07
    --
    -- This procedure handles merging
    --
    -- Recordsets:
    -- The contents of our table valued parameter will be echoed back to the 
    -- caller.
    --
    -- Side-effects:
    -- None
    --
    -- See also:
    -- your mom
    --
    -- Modified:
    --
    -----------------------------------------------------------------------------
    CREATE PROCEDURE dbo.EchoBack
    (
        @tvp dbo.CONTRIVED_EXAMPLE READONLY
    )
    AS
    BEGIN
        SET NOCOUNT ON
    
        SELECT
            T.*
        FROM
            @tvp T
    
    END
    GO
    PRINT 'Granting rights for dbo.EchoBack'
    GRANT EXECUTE ON dbo.EchoBack TO public
    GO
    DECLARE @p1 dbo.CONTRIVED_EXAMPLE 
    INSERT INTO @p1 values('billinkc', 1)
    INSERT INTO @p1 values('peschkaj', 1)
    INSERT INTO @p1 values('mikeSQL', 1)
    INSERT INTO @p1 values('SQLChicken', 0)
    
    SELECT * FROM @p1
    
    EXECUTE dbo.EchoBack @p1
    GO
    IF EXISTS
    (
        SELECT
            SO.*
        FROM
            dbo.sysobjects SO
        WHERE
            SO.id = OBJECT_ID('dbo.TwitterAdd')
            AND OBJECTPROPERTY(SO.id, 'IsProcedure') = 1
    )
    BEGIN
        PRINT 'Dropping stored procedure dbo.TwitterAdd'
        DROP PROCEDURE dbo.TwitterAdd
    END
    GO
    PRINT 'Creating stored procedure dbo.TwitterAdd'
    GO
    -----------------------------------------------------------------------------
    -- Function: dbo.TwitterAdd
    -- Author: Bill Fellows
    -- Date: 2010-06-07
    --
    -- This procedure handles merging
    --
    -- Recordsets:
    -- Business rule violations (optional)
    --
    -- Side-effects:
    -- 0-N rows written to twitter table
    --
    -- See also:
    -- CONTRIVED_EXAMPLE (your mom)
    --
    -- Modified:
    --
    -----------------------------------------------------------------------------
    CREATE PROCEDURE dbo.TwitterAdd
    (
        @tvp dbo.CONTRIVED_EXAMPLE READONLY
    )
    AS
    BEGIN
        SET NOCOUNT ON
    
        MERGE
            dbo.CONTRIVED_EXAMPLE_TABLE DESTINATION
        USING
            (SELECT twitter_handle, have_met FROM @tvp T) AS SOURCE (twitter_handle, have_met)
            ON (SOURCE.twitter_handle = DESTINATION.twitter_handle)
            -- Never forget I met someone
        WHEN MATCHED AND DESTINATION.have_met = 0
            THEN UPDATE SET DESTINATION.have_met = SOURCE.have_met
        WHEN NOT MATCHED
            THEN INSERT(twitter_handle, have_met) VALUES (SOURCE.twitter_handle, SOURCE.have_met)
            -- merge statements must be terminated by a semi-colon
            -- and don't you forget it!
            ;
    
    END
    GO
    PRINT 'Granting rights for dbo.TwitterAdd'
    GRANT EXECUTE ON dbo.TwitterAdd TO public
    GO
    

    この時点で、TVP がどのように機能するかを確認できます。残りの唯一のステップは、それを .NET コードに結び付けることです。のようなもの

    /// <summary>
    /// This method demonstrates the ease of passing a dataset in
    /// as a TVP
    /// </summary>
    public static void TSQLTuesday007()
    {
        string connectionString = @"Data Source=localhost;Initial Catalog=master;Integrated Security=True";
        System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(connectionString);
        System.Data.DataTable dataTable = null;
    
        // note that my data table does not have to be the same
        // as my UDTT, nor do my columns have to have the same name
        // Types-yes. Ordinal, probably so
        dataTable = new System.Data.DataTable("Sample");
        dataTable.Columns.Add("tweep", System.Type.GetType("System.String"));
        dataTable.Columns.Add("have_met", System.Type.GetType("System.Boolean"));
    
        // add rows to my data table but really, this could be any source
        dataTable.Rows.Add(new object[] { "billinkc", true });
        dataTable.Rows.Add(new object[] { "BrentO", true });
        dataTable.Rows.Add(new object[] { "buckwoody", false });
    
        // Hooray for #sqlsat35 and meeting Jen & Sean
        dataTable.Rows.Add(new object[] { "MidnightDBA", true });
    
        System.Data.SqlClient.SqlConnection connection = null;
        System.Data.DataSet results = null;
        System.Data.SqlClient.SqlCommand command = null;
        System.Data.SqlClient.SqlDataReader dataReader = null;
        connection = new System.Data.SqlClient.SqlConnection(connectionString);
        try
        {
            connection.Open();
            command = new System.Data.SqlClient.SqlCommand("TwitterAdd");
            command.CommandType = System.Data.CommandType.StoredProcedure;
            command.Connection = connection;
    
            // Assigning a table valued parameter looks much like any other parameter
            System.Data.SqlClient.SqlParameter tvp = command.Parameters.AddWithValue("@tvp", dataTable);
    
            // this is the only special sauce (not required but helpful)
            tvp.SqlDbType = System.Data.SqlDbType.Structured;
            tvp.TypeName = "dbo.CONTRIVED_EXAMPLE";
    
            dataReader = command.ExecuteReader();
            if (dataReader.HasRows)
            {
                results = new System.Data.DataSet();
                results.Tables.Add();
                results.Tables[0].Load(dataReader);
                // PPrint(results);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }
    }
    



    1. INSERT ... SELECT ... WHERE ... ON DUPLICATE...mysqlクエリ

    2. MySQLにSQLServerのSETNOCOUNTに相当するものはありますか?

    3. Nullを含むMySQLGROUP_CONCAT

    4. すべてのストアドプロシージャに実行を許可します