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

高度なSQL:パラメーター化されたテーブル値関数の出力をSQLテーブルに挿入します

    この記事では、次のことを説明します。

    1. テーブル値関数の出力をSQLテーブルに挿入する方法。
    2. リモートデータベースサーバーで作成されたテーブル値関数の出力を挿入する方法。

    「挿入」ステートメントとは

    RDBMSでは、「Insertinto」は基本的なSQLステートメントの1つです。 SQLテーブルに新しいレコードを挿入するために使用されます。ステートメントを使用して、次のタスクを実行できます。

    • テーブルに新しいレコードを挿入します(基本挿入)。
    • テーブルの特定の列の値を挿入します。
    • ストアドプロシージャによって生成された出力をSQLテーブルに挿入します。

    上記を示すために、「学生」という名前のテーブルを作成しましょう。 」をDemoDatabaseに表示します。次のコードを実行して、テーブルを作成します。

    CREATE TABLE STUDENTS 
      ( 
         ID        	INT IDENTITY(1, 1) PRIMARY KEY, 
         FIRSTNAME 	VARCHAR(250), 
         LASTNAME  	VARCHAR(250), 
         ADMISSIONDATE  DATETIME,
         GRADE     	CHAR(1) 
      )

    基本的な挿入を実行する

    基本的な挿入を実行するには、ターゲットテーブルの名前とテーブルの値を指定する必要があります。以下は、基本的な挿入ステートメントの基本的な構文です。

    INSERT INTO <target TABLE NAME> VALUES 
                ( 
                            <value FOR COLUMN 1 >, 
                            <value FOR COLUMN 1 >.. 
                )

    たとえば、「Students」テーブルに3人の学生の名、姓、および学年を挿入します。これを行うには、次のコードを実行します。

    INSERT INTO STUDENTS 
    VALUES      ('NISARG', 
                 'UPADHYAY', 
                 '2018-09-11', 
                 'A'), 
                ('RAGHAV', 
                 'DATTA', 
                 '2017-10-01', 
                 'A'), 
                ('KIRAN', 
                 'AMIN', 
                 '2016-01-31', 
                 'A')

    「Student」に対して「Select」クエリを実行して、結果を確認します。

    SELECT FIRSTNAME, 
           LASTNAME, 
           ADMISSIONDATE, 
           GRADE 
    FROM   STUDENTS

    結果は次のとおりです。

    テーブルの特定の列の値を挿入します

    テーブルの特定の列に値を挿入するには、ターゲットテーブルの名前と、データを挿入する列の名前を指定する必要があります。構文は次のとおりです。

    INSERT INTO <TARGET TABLE NAME> 
                ( 
                            COLUMN 1 , 
                            COLUMN 2 
                ) 
                VALUES 
                ( 
                            <VALUE FOR COLUMN 1 >, 
                            <VALUE FOR COLUMN 1 >.. 
                )

    たとえば、「学生」に2人の学生の名前と名前を挿入します。 " テーブル。これを行うには、次のコードを実行します。

    INSERT INTO STUDENTS 
                (FIRSTNAME, 
                 LASTNAME) 
    VALUES      ('NIMESH', 
                 'UPADHYAY'), 
                ('RUPESH', 
                 'DATTA')

    学生」に対して「選択」クエリを実行します 」テーブル。

    SELECT FIRSTNAME, 
           LASTNAME, 
           ADMISSIONDATE, 
           GRADE 
    FROM   STUDENTS

    出力は次のようになります。

    出力を挿入し、ストアドプロシージャによって生成します

    ストアドプロシージャの出力をテーブルに挿入するには、ターゲットテーブル名とソースストアドプロシージャを指定する必要があります。ストアドプロシージャの出力を生成するには、「exec」または「EXECUTE」キーワードを使用する必要があります。したがって、テーブル名または列の名前の後に「exec」キーワードを指定する必要があります。構文は次のとおりです。

    INSERT INTO <TARGET TABLE NAME> 
                ( 
                            COLUMN 1 , 
                            COLUMN 2 
                ) 
    EXEC <PROCEDURENAME>

    たとえば、入学日がnullではない学生の名前を入力するプロシージャの出力を挿入したいとします。そのために、「 spGet_Student_AdmissionDate」という名前のストアドプロシージャを作成します 」。ストアドプロシージャを作成するには、次のコードを実行します。

    USE DEMODATABASE 
    
    GO 
    
    CREATE PROCEDURE SPGET_STUDENT_ADMISSIONDATE 
    AS 
      BEGIN 
          SELECT ISNULL(FIRSTNAME, '') + ' ' 
                 + ISNULL(LASTNAME, '') AS STUDENTNAME, 
                 ADMISSIONDATE, 
                 GRADE 
          FROM   STUDENTS 
          WHERE  ADMISSIONDATE IS NOT NULL 
      END

    プロシージャが作成されたら、次のコードを実行してプロシージャを実行します。

    EXECUTE spGet_Student_Admissiondate

    出力は次のようになります。

    上で述べたように、「 spGet_Student_Admissiondate」という名前のストアドプロシージャの出力を挿入します。 」を一時テーブルに追加します。まず、次のコードを実行してテーブルを作成します。

      ( 
         ID            INT IDENTITY(1, 1), 
         STUDENTNAME   VARCHAR(250), 
         ADMISSIONDATE DATETIME, 
         GRADE         CHAR(1) 
      )

    テーブルが作成されたら、次のコードを実行して「 spGet_Student_Admissiondate」の出力を挿入します 」から「#TempStudents 」。

    INSERT INTO #TEMPSTUDENTS 
    EXECUTE SPGET_STUDENT_ADMISSIONDATE 
    Output: (3 rows affected)

    それでは、「 #TEMPSTUDENTS」の出力を確認してみましょう。 」。これを行うには、次のコードを実行します。

    ここで、前述したように、テーブル値関数によって生成された出力をSQLテーブルに挿入する方法を示します。まず、テーブル値関数とは何かを理解しましょう。

    テーブル値関数とは

    テーブル値関数は、パラメーターを受け入れ、変数で定義された条件に基づいて、テーブル変数で結果セットを返す特別なT-SQLコードです。表値関数を使用する利点は次のとおりです。

    1. Selectクエリ内で実行できます。
    2. クエリの複数の部分で使用できます。たとえば、Caseステートメントのwhere/having句で使用できます。
    3. テーブル値関数の出力はレコードセットであるため、関数をテーブルと結合できます。

    SQLテーブルにインラインテーブル値関数の出力を挿入

    このセクションでは、T-SQLを使用してテーブル値関数の出力をSQLテーブルに挿入する方法について説明します。

    デモンストレーションには、AdventureWorks2014データベースを使用しています。 「GetEmployeesbyHireDate」という名前のインライン複数値テーブル関数を作成しました 。」この関数は、特定の日時に雇用された従業員の情報を入力します。この関数は@FormDateを使用します および@Toda データをフィルタリングするためのパラメータ。関数の出力はSQLテーブルに保存されます。

    次のコードは関数を作成します:

    CREATE FUNCTION GETEMPLOYEESBYHIREDATE (@FROMDATE AS DATETIME, 
                                            @TODATE   AS DATETIME) 
    RETURNS @EMPLOYEES TABLE ( 
      EMPLOYEENAME VARCHAR (MAX), 
      BIRTHDATE    DATETIME, 
      JOBTITLE     VARCHAR(150), 
      EMAILID      VARCHAR(100), 
      PHONENUMBER  VARCHAR(20), 
      HIREDATE     DATETIME ) 
    AS 
      BEGIN 
          INSERT INTO @EMPLOYEES 
          SELECT ( ISNULL( B.FIRSTNAME, '') + ' ' 
                   + ISNULL( B.MIDDLENAME, '') + ' ' 
                   + ISNULL( B.LASTNAME, '') )AS EMPLOYEENAME, 
                 A.BIRTHDATE, 
                 B.JOBTITLE, 
                 B.EMAILADDRESS, 
                 B.PHONENUMBER, 
                 A.HIREDATE 
          FROM   [HUMANRESOURCES].[EMPLOYEE] A 
                 INNER JOIN [HUMANRESOURCES].[VEMPLOYEE] B 
                         ON A.BUSINESSENTITYID = B.BUSINESSENTITYID 
          WHERE  A.HIREDATE BETWEEN @FROMDATE AND @TODATE 
    
          RETURN 
      END

    Selectクエリを使用して、SQL関数の出力を取得できます。たとえば、2009年以内に採用された従業員のリストを作成するとします。次のクエリを実行して、リストを取得します。

    DECLARE @FROMDT DATETIME 
    DECLARE @TODT DATETIME 
    
    SET @FROMDT='2009-01-01' 
    SET @TODT='2009-12-31' 
    
    SELECT * 
    FROM   GETEMPLOYEESBYHIREDATE(@FROMDT, @TODT)

    上記のクエリの出力は次のようになります。

    次に、「 tblEmploye」という名前のテーブルを作成します e」は、「 GetEmployeesbyHiredate」の出力を保存します " 働き。次のコードは、「 tblEmployee」という名前のテーブルを作成します 」。

    CREATE TABLE TBLEMPLOYEES 
      ( 
         EMPLOYEENAME VARCHAR (MAX), 
         BIRTHDATE    DATETIME, 
         JOBTITLE     VARCHAR(150), 
         EMAILID      VARCHAR(100), 
         PHONENUMBER  VARCHAR(20), 
         HIREDATE     DATETIME 
      )

    前述したように、2009年に採用された従業員の情報を入力します。これを行うには、 GetEmployeesbyHireDateの出力を挿入します。 tblEmployeesで機能する テーブル。これを行うには、次のコードを実行します。

    DECLARE @FROMDT DATETIME 
    DECLARE @TODT DATETIME 
    
    SET @FROMDT='2009-01-01' 
    SET @TODT='2009-12-31' 
    
    INSERT INTO TBLEMPLOYEES 
    SELECT EMPLOYEENAME, 
           BIRTHDATE, 
           JOBTITLE, 
           EMAILID, 
           PHONENUMBER, 
           HIREDATE 
    FROM   GETEMPLOYEESBYHIREDATE(@FROMDT, @TODT)

    データがテーブルに挿入されていることを確認しましょう。これを行うには、次のコードを実行します。

    SELECT * 
    FROM   TBLEMPLOYEES

    出力は次のようになります。

    リモートデータベースのテーブルにデータを挿入

    別のデータセンターに保存されているサーバーからデータを抽出したい場合があります。これは、SQLリンクサーバーを使用して実行できます。

    このセクションでは、リモートサーバーで作成されたテーブル値関数の出力を挿入する方法について説明します。シナリオを示すために、以下はセットアップです。

    [テーブルID=57 /]

    デモでは、次のタスクを実行します。

    1. ソースサーバー上( SQL_VM_1 )、「 getCustomerByCountry」という名前のテーブル値関数を作成します 」の「AdventureWorks2014 」データベースを使用してデータを入力します。
    2. 宛先サーバーで、「 Remote_Server」という名前のリンクサーバーを作成します 」を使用して関数を実行します( getCustomerByCountry
    3. 宛先サーバーで、「 Customer」という名前のテーブルを作成します 」は、リモート関数( getCustomerByCountry )によって取得されたデータを保存します 。

    次の画像はセットアップを示しています。

    ソースサーバーで実行するタスク:

    ソースサーバー上(SQL_VM_1 )、「 getCustomerByCountry」という名前の関数を作成します 。」特定の国または地域にいる顧客の詳細を入力します。この関数は@CountryNameを使用します データをフィルタリングするパラメータ。次のコードを実行して関数を作成します。

    Alter FUNCTION Getcustomerbycountry(@CountryName VARCHAR)
    returns @Customers TABLE (
      customer_name VARCHAR(500),
      phoennumber   VARCHAR(50),
      emailaddress  VARCHAR(100),
      address       VARCHAR(max),
      city          VARCHAR(150),
      country       VARCHAR(250),
      postalcode    VARCHAR(50))
    AS
      BEGIN
          INSERT INTO @Customers
          SELECT customer_name,
                 phoennumber,
                 emailaddress,
                 address,
                 city,
                 country,
                 postalcode
          FROM   customers
          WHERE  country [email protected]
    
          RETURN
      END

    宛先サーバーで実行されるタスク:

    ソースサーバーからデータを入力するには( SQL_VM_1 )、最初に、ソース( SQL_VM_1 )間にリンクサーバーを作成します )および宛先(SQL_VM _ 2)。移行先サーバー( SQL_VM_2 )で次のコードを実行します )リンクサーバーを作成します。

    USE [MASTER]
    GO
    EXEC MASTER.DBO.SP_ADDLINKEDSERVER @SERVER = N'SQL_VM_1', @SRVPRODUCT=N'SQL SERVER'
    GO
    EXEC MASTER.DBO.SP_ADDLINKEDSRVLOGIN @RMTSRVNAME=N' Remote_Server',@USESELF=N'FALSE',@LOCALLOGIN=NULL,@RMTUSER=N'SA',@RMTPASSWORD='########'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'COLLATION COMPATIBLE', @OPTVALUE=N'TRUE'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'DATA ACCESS', @OPTVALUE=N'TRUE'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'DIST', @OPTVALUE=N'FALSE'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'PUB', @OPTVALUE=N'FALSE'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'RPC', @OPTVALUE=N'TRUE'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'RPC OUT', @OPTVALUE=N'TRUE'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'SUB', @OPTVALUE=N'FALSE'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'CONNECT TIMEOUT', @OPTVALUE=N'0'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'COLLATION NAME', @OPTVALUE=NULL
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'LAZY SCHEMA VALIDATION', @OPTVALUE=N'FALSE'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'QUERY TIMEOUT', @OPTVALUE=N'0'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'USE REMOTE COLLATION', @OPTVALUE=N'TRUE'
    GO
    EXEC MASTER.DBO.SP_SERVEROPTION @SERVER=N'Remote_Server', @OPTNAME=N'REMOTE PROC TRANSACTION PROMOTION', @OPTVALUE=N'FALSE'
    GO

    リンクサーバーが作成されたら、顧客の情報を格納するSQLテーブルを作成し、ソースサーバー( SQL_VM_1 )で作成されたSQL関数を実行してデータを入力します。 。

    次のコードを実行してテーブルを作成します。

    USE DEMODATABASE
    GO
    CREATE TABLE CUSTOMERS
      (
         ID            INT IDENTITY(1, 1),
         CUSTOMER_NAME VARCHAR(500),
         PHONENUMBER   VARCHAR(50),
         EMAILADDRESS VARCHAR(100),
         ADDRESS       VARCHAR(MAX),
         CITY          VARCHAR(150),
         COUNTRY       VARCHAR(250),
         POSTALCODE    VARCHAR(50)
      )

    リンクサーバーを使用して、リモートデータベースサーバーで作成されたテーブル値関数を実行できます。リンクサーバーを使用して関数を実行しようとすると、次のエラーが発生します。

    Msg 4122, Level 16, State 1, Line 28
    Remote table-valued function calls are not allowed.

    したがって、リモートサーバーで関数を実行するには、OPENQUERYキーワードを使用する必要があります。リンクサーバーを使用してアドホック分散クエリを初期化するために使用されます。 OPENQUERYの概念を理解するには、この記事を参照してください。

    OPENQUERYを使用するには、「アドホック分散クエリ」という名前の高度な構成パラメータを有効にする必要があります。 ソースサーバーと宛先サーバーの」。次のコードを実行して有効にします。

    USE MASTER
    GO
    EXEC SP_CONFIGURE 'SHOW ADVANCED OPTION', 1
    RECONFIGURE WITH OVERRIDE
    EXEC SP_CONFIGURE 'AD HOC DISTRIBUTED QUERIES', 1
    RECONFIGURE WITH OVERRIDE

    次に、英国にいる顧客のリストを作成して、「顧客」に挿入します。 " テーブル。前述したように、この関数は国名を受け入れてレコードをフィルタリングします。次に、宛先サーバー( SQL_VM_2 )で次のスクリプトを実行する必要があります。 )「英国」にいる顧客のリストを作成します。

    SELECT CUSTOMER_NAME, 
           PHOENNUMBER, 
           EMAILADDRESS, 
           ADDRESS, 
           CITY, 
           COUNTRY, 
           POSTALCODE 
    FROM   OPENQUERY([TTI609-VM2], 
    'DECLARE @COUNTRY VARCHAR(150)
    SET @COUNTRY=''UNITED KINGDOM''    
    SELECT * FROM [ADVENTUREWORKS2014].DBO.GETCUSTOMERBYCOUNTRY(''''+ @COUNTRY +'''')' 
    )

    出力は次のようになります。

    ここで、「Customers」テーブルに入力されたデータを挿入するには、宛先サーバー( SQL_VM_2 )で次のスクリプトを実行します。 。

    INSERT INTO CUSTOMERS (CUSTOMER_NAME,PHONENUMBER,EMAILADDRESS,ADDRESS,CITY,COUNTRY,POSTALCODE)
    SELECT CUSTOMER_NAME, 
           PHOENNUMBER, 
           EMAILADDRESS, 
           ADDRESS, 
           CITY, 
           COUNTRY, 
           POSTALCODE 
    FROM   OPENQUERY([TTI609-VM2], 
    'DECLARE @COUNTRY VARCHAR(150)
    SET @COUNTRY=''UNITED KINGDOM''    
    SELECT * FROM [ADVENTUREWORKS2014].DBO.GETCUSTOMERBYCOUNTRY(''''+ @COUNTRY +'''')' 
    )
    
    /*Output*/
    
    (1913 rows affected)

    次に、データが正しく挿入されているかどうかを確認しましょう。確認するには、宛先サーバー(SQL_VM_2)で次のクエリを実行します。

    USE DEMODATABASE
    GO
    SELECT TOP 20 CUSTOMER_NAME, 
           PHONENUMBER, 
           EMAILADDRESS, 
           ADDRESS, 
           CITY, 
           COUNTRY, 
           POSTALCODE 
    FROM   CUSTOMERS

    出力は次のようになります。

    概要

    この記事で取り上げたのは:

    1. 「InsertInto」ステートメントとその使用法。
    2. テーブル値関数の出力をSQLテーブルに保存する方法。
    3. リンクサーバーを使用して、テーブル値関数の出力をリモートサーバーにあるSQLテーブルに保存する方法。

    1. MySqlエラー:1364フィールド'display_name'にデフォルト値がありません

    2. postgresqlシングルインスタンスインストール

    3. T-SQLの文字列から拡張ASCII文字を削除するにはどうすればよいですか?

    4. LEFT()関数がSQL Server(T-SQL)でどのように機能するか