데이터 집합 보내기 예제

DataSet 보내기 예제에서는 서버 쪽 CLR(공용 언어 런타임) 기반 저장 프로시저 내에서 ADO.NET 기반 DataSet을 결과 집합으로 클라이언트에 반환하는 방법을 보여 줍니다. 예를 들어 이러한 저장 프로시저가 쿼리 결과를 사용하여 DataSet을 채운 다음 이 DataSet에 있는 데이터를 조작하는 경우 이 예제가 유용합니다. 저장 프로시저가 DataSet을 처음부터 만들고 채우는 경우에도 이 예제가 유용합니다. 이 예제는 두 개의 클래스인 DataSetUtilities와 TestSendDataSet으로 구성됩니다. 일반적으로 DataSetUtilities 클래스의 SendDataSet 메서드가 DataSet 인스턴스의 내용을 클라이언트로 전송합니다. TestSendDataSet 클래스에 정의된 DoTest 메서드는 DataSet을 만들고 이 DataSet을 uspGetTwoBOMTestData Transact-SQL 저장 프로시저의 데이터로 채움으로써 SendDataSet 메서드가 작동하는지 확인합니다. uspGetTwoBOMTestData는 Transact-SQL 저장 프로시저인 uspGetBillOfMaterials를 두 번 실행하여 usp_GetTwoBOMTestData 저장 프로시저에 대한 매개 변수로 지정된 두 제품의 제품 구성 정보(BOM)를 재귀적으로 쿼리합니다. 일반적으로 데이터 집합을 채운 후에는 SendDataSet을 호출하여 데이터 집합 내의 데이터를 결과 집합으로 클라이언트에 배달하기 전에 데이터가 수정됩니다. 간단하게 하기 위해 이 예제에서는 데이터를 수정하지 않고 반환합니다.

필수 구성 요소

이 프로젝트를 만들고 실행하려면 다음 소프트웨어가 설치되어 있어야 합니다.

  • SQL Server 또는 SQL Server Express SQL Server Express는 SQL Server Express 설명서 및 예제 웹 사이트에서 무료로 구할 수 있습니다.

  • SQL Server 개발자 웹 사이트에서 제공되는 AdventureWorks 데이터베이스

  • .NET Framework SDK 2.0 이상 또는 Microsoft Visual Studio 2005 이상. .NET Framework SDK는 무료로 구할 수 있습니다.

  • 또한 다음 조건을 충족해야 합니다.

  • 사용하고 있는 SQL Server 인스턴스에 대해 CLR 통합이 설정되어 있어야 합니다.

  • CLR 통합을 설정하려면 다음 단계를 수행합니다.

    CLR 통합 사용

    • 다음 Transact-SQL 명령을 실행합니다.

    sp_configure 'clr enabled', 1

    GO

    RECONFIGURE

    GO

    [!참고]

    CLR을 설정하려면 ALTER SETTINGS 서버 수준 사용 권한이 있어야 합니다. 이 사용 권한은 sysadmin 및 serveradmin 고정 서버 역할의 멤버가 암시적으로 소유합니다.

  • 사용하고 있는 SQL Server 인스턴스에 AdventureWorks 데이터베이스를 설치해야 합니다.

  • 사용 중인 SQL Server 인스턴스의 관리자가 아닌 경우 설치를 완료하기 위해 관리자로부터 CreateAssembly 권한을 부여 받아야 합니다.

예제 빌드

다음 지침을 사용하여 예제를 만들고 실행합니다.

  1. Visual Studio 또는 .NET Framework 명령 프롬프트를 엽니다.

  2. 필요한 경우 예제에 대한 디렉터리를 만듭니다. 이 예에서는 C:\MySample을 사용합니다.

  3. c:\MySample에서 SendDataSet.vb(Visual Basic 예제용) 또는 SendDataSet.cs(C# 예제용)를 만들고 적합한 Visual Basic 또는 C# 예제 코드(아래)를 파일에 복사합니다.

  4. 선택하는 언어에 따라 다음 중 하나를 실행하여 명령줄 프롬프트에서 예제 코드를 필수 어셈블리로 컴파일합니다.

    • Vbc /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll,C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll,C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /target:library SendDataSet.vb

    • Csc /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /target:library SendDataSet.cs

  5. Transact-SQL 설치 코드를 파일에 복사하고 해당 파일을 예제 디렉터리에 Install.sql로 저장합니다.

  6. 예제가 C:\MySample\ 이외의 디렉터리에 설치된 경우 Install.sql 파일이 해당 위치를 가리키도록 표시된 대로 편집합니다.

  7. 다음을 실행하여 어셈블리, 저장 프로시저 및 함수를 배포합니다.

    • sqlcmd -E -I -i install.sql
  8. Transact-SQL 테스트 스크립트를 파일에 복사하고 해당 파일을 예제 디렉터리에 test.sql로 저장합니다.

    • sqlcmd -E -I -i test.sql
  9. Transact-SQL 정리 스크립트를 파일에 복사하고 해당 파일을 예제 디렉터리에 cleanup.sql로 저장합니다.

  10. 다음 명령으로 스크립트를 실행합니다.

    • sqlcmd -E -I -i cleanup.sql

예제 코드

다음은 이 예제에 대한 코드 목록입니다.

C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;


    public static class DataSetUtilities
    {

        public static void SendDataSet(DataSet ds)
        {
            if (ds == null)
            {
                throw new ArgumentException("SendDataSet requires a non-null data set.");
            }
            else
            {
                foreach (DataTable dt in ds.Tables)
                {
                    SendDataTable(dt);
                }
            }
        }


        public static void SendDataTable(DataTable dt)
        {
            bool[] coerceToString;  // Do we need to coerce this column to string?
            SqlMetaData[] metaData = ExtractDataTableColumnMetaData(dt, out coerceToString);

            SqlDataRecord record = new SqlDataRecord(metaData);
            SqlPipe pipe = SqlContext.Pipe;
            pipe.SendResultsStart(record);
            try
            {
                foreach (DataRow row in dt.Rows)
                {
                    for (int index = 0; index < record.FieldCount; index++)
                    {
                        object value = row[index];
                        if (null != value && coerceToString[index])
                            value = value.ToString();
                        record.SetValue(index, value);
                    }

                    pipe.SendResultsRow(record);
                }
            }
            finally
            {
                pipe.SendResultsEnd();
            }
        }

        private static SqlMetaData[] ExtractDataTableColumnMetaData(DataTable dt, out bool[] coerceToString)
        {
            SqlMetaData[] metaDataResult = new SqlMetaData[dt.Columns.Count];
            coerceToString = new bool[dt.Columns.Count];
            for (int index = 0; index < dt.Columns.Count; index++)
            {
                DataColumn column = dt.Columns[index];
                metaDataResult[index] = SqlMetaDataFromColumn(column, out coerceToString[index]);
            }

            return metaDataResult;
        }

        private static Exception InvalidDataTypeCode(TypeCode code)
        {
            return new ArgumentException("Invalid type: " + code);
        }

        private static Exception UnknownDataType(Type clrType)
        {
            return new ArgumentException("Unknown type: " + clrType);
        }

        private static SqlMetaData SqlMetaDataFromColumn(DataColumn column, out bool coerceToString)
        {
            coerceToString = false;
            SqlMetaData sql_md = null;
            Type clrType = column.DataType;
            string name = column.ColumnName;
            switch (Type.GetTypeCode(clrType))
            {
                case TypeCode.Boolean: sql_md = new SqlMetaData(name, SqlDbType.Bit); break;
                case TypeCode.Byte: sql_md = new SqlMetaData(name, SqlDbType.TinyInt); break;
                case TypeCode.Char: sql_md = new SqlMetaData(name, SqlDbType.NVarChar, 1); break;
                case TypeCode.DateTime: sql_md = new SqlMetaData(name, SqlDbType.DateTime); break;
                case TypeCode.DBNull: throw InvalidDataTypeCode(TypeCode.DBNull);
                case TypeCode.Decimal: sql_md = new SqlMetaData(name, SqlDbType.Decimal, 18, 0); break;
                case TypeCode.Double: sql_md = new SqlMetaData(name, SqlDbType.Float); break;
                case TypeCode.Empty: throw InvalidDataTypeCode(TypeCode.Empty);
                case TypeCode.Int16: sql_md = new SqlMetaData(name, SqlDbType.SmallInt); break;
                case TypeCode.Int32: sql_md = new SqlMetaData(name, SqlDbType.Int); break;
                case TypeCode.Int64: sql_md = new SqlMetaData(name, SqlDbType.BigInt); break;
                case TypeCode.SByte: throw InvalidDataTypeCode(TypeCode.SByte);
                case TypeCode.Single: sql_md = new SqlMetaData(name, SqlDbType.Real); break;
                case TypeCode.String: sql_md = new SqlMetaData(name, SqlDbType.NVarChar, column.MaxLength);
                    break;
                case TypeCode.UInt16: throw InvalidDataTypeCode(TypeCode.UInt16);
                case TypeCode.UInt32: throw InvalidDataTypeCode(TypeCode.UInt32);
                case TypeCode.UInt64: throw InvalidDataTypeCode(TypeCode.UInt64);
                case TypeCode.Object:
                    sql_md = SqlMetaDataFromObjectColumn(name, column, clrType);
                    if (sql_md == null)
                    {
                        // Unknown type, try to treat it as string;
                        sql_md = new SqlMetaData(name, SqlDbType.NVarChar, column.MaxLength);
                        coerceToString = true;
                    }
                    break;

                default: throw UnknownDataType(clrType);
            }

            return sql_md;
        }

        private static SqlMetaData SqlMetaDataFromObjectColumn(string name, DataColumn column, Type clrType)
        {
            SqlMetaData sql_md = null;
            if (clrType == typeof(System.Byte[]) || clrType == typeof(SqlBinary) || clrType == typeof(SqlBytes) ||
        clrType == typeof(System.Char[]) || clrType == typeof(SqlString) || clrType == typeof(SqlChars))
                sql_md = new SqlMetaData(name, SqlDbType.VarBinary, column.MaxLength);
            else if (clrType == typeof(System.Guid))
                sql_md = new SqlMetaData(name, SqlDbType.UniqueIdentifier);
            else if (clrType == typeof(System.Object))
                sql_md = new SqlMetaData(name, SqlDbType.Variant);
            else if (clrType == typeof(SqlBoolean))
                sql_md = new SqlMetaData(name, SqlDbType.Bit);
            else if (clrType == typeof(SqlByte))
                sql_md = new SqlMetaData(name, SqlDbType.TinyInt);
            else if (clrType == typeof(SqlDateTime))
                sql_md = new SqlMetaData(name, SqlDbType.DateTime);
            else if (clrType == typeof(SqlDouble))
                sql_md = new SqlMetaData(name, SqlDbType.Float);
            else if (clrType == typeof(SqlGuid))
                sql_md = new SqlMetaData(name, SqlDbType.UniqueIdentifier);
            else if (clrType == typeof(SqlInt16))
                sql_md = new SqlMetaData(name, SqlDbType.SmallInt);
            else if (clrType == typeof(SqlInt32))
                sql_md = new SqlMetaData(name, SqlDbType.Int);
            else if (clrType == typeof(SqlInt64))
                sql_md = new SqlMetaData(name, SqlDbType.BigInt);
            else if (clrType == typeof(SqlMoney))
                sql_md = new SqlMetaData(name, SqlDbType.Money);
            else if (clrType == typeof(SqlDecimal))
                sql_md = new SqlMetaData(name, SqlDbType.Decimal, SqlDecimal.MaxPrecision, 0);
            else if (clrType == typeof(SqlSingle))
                sql_md = new SqlMetaData(name, SqlDbType.Real);
            else if (clrType == typeof(SqlXml))
                sql_md = new SqlMetaData(name, SqlDbType.Xml);
            else
                sql_md = null;

            return sql_md;
        }
                  
    }
 public static class TestSendDataSet
    {
        private const string TestConnectionString = "context connection=true";
        const int prod1ID = 750; //Product ID of Road-150 Red, 44 bicycle
        const int prod2ID = 751; //Product ID of Road-150 Red, 48 bicycle

        /// <summary>
        /// Invoke a stored procedure to get some bill of material information and 
        /// fill a data set with the two result sets.  Return the data set to the client.
        /// </summary>
        public static void DoTest()
        {
            using (SqlConnection conn = new SqlConnection(TestConnectionString))
            {
                SqlCommand cmd = conn.CreateCommand();
                cmd.CommandText = "usp_GetTwoBOMTestData";
                cmd.CommandType = CommandType.StoredProcedure;

                SqlParameter prod1Param = new SqlParameter("@ProductID1", SqlDbType.Int);
                prod1Param.Value = prod1ID;
                cmd.Parameters.Add(prod1Param);

                SqlParameter prod2Param = new SqlParameter("@ProductID2", SqlDbType.Int);
                prod2Param.Value = prod2ID;
                cmd.Parameters.Add(prod2Param);

                SqlParameter asOfDateParam = new SqlParameter("@AsOfDate", SqlDbType.DateTime);
                asOfDateParam.Value = DateTime.Now;
                cmd.Parameters.Add(asOfDateParam);

                DataSet ds = new DataSet("TestData");
                SqlDataAdapter sda = new SqlDataAdapter(cmd);
                conn.Open();
                sda.Fill(ds);

// Normally, after filling the data set, rather than immediately returning it, 
// the data would be modified before invoking SendDataSet to deliver 
// the data within the data set as a result set to the client.  For simplicity 
// this sample simply returns the data.

                DataSetUtilities.SendDataSet(ds);

            }
        }

    }

Visual Basic

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Data
Imports System.Diagnostics
Imports System.Collections.Generic
Imports System.Text
Imports System.Data.SqlClient
Imports System.Data.SqlTypes
Imports Microsoft.SqlServer.Server
Imports System.Runtime.InteropServices

Public Class DataSetUtilities

    Public Shared Sub SendDataSet(ByVal ds As DataSet)
        If ds Is Nothing Then
            Throw New ArgumentException("SendDataSet requires a non-null data set.")
        Else
            For Each dt As DataTable In ds.Tables
                SendDataTable(dt)
            Next
        End If
    End Sub

    Public Shared Sub SendDataTable(ByVal dt As DataTable)
        Dim coerceToString() As Boolean = Nothing ' Do we need to coerce this column to string?
        Dim metaData As SqlMetaData() = ExtractDataTableColumnMetaData(dt, coerceToString)

        Dim record As New SqlDataRecord(metaData)
        Dim pipe As SqlPipe = SqlContext.Pipe
        pipe.SendResultsStart(record)

        Try
            For Each row As DataRow In dt.Rows
                For index As Integer = 0 To record.FieldCount - 1
                    Dim value As Object = row(index)
                    If Nothing Is value AndAlso coerceToString(index) Then
                        value = value.ToString()
                    End If

                    record.SetValue(index, value)
                Next

                pipe.SendResultsRow(record)
            Next
        Finally
            pipe.SendResultsEnd()
        End Try
    End Sub

    Private Shared Function ExtractDataTableColumnMetaData(ByVal dt As DataTable, <Out()> ByRef coerceToString() As Boolean) As SqlMetaData()
        Dim metaDataResult(dt.Columns.Count - 1) As SqlMetaData
        coerceToString = New Boolean(dt.Columns.Count - 1) {}
        For index As Integer = 0 To dt.Columns.Count - 1
            Dim column As DataColumn = dt.Columns(index)
            metaDataResult(index) = SqlMetaDataFromColumn(column, coerceToString(index))
        Next

        Return metaDataResult
    End Function
    Private Shared Function InvalidDataTypeCode(ByVal code As TypeCode) As Exception
        Return New ArgumentException("Invalid type: " & code.ToString())
    End Function

    Private Shared Function UnknownDataType(ByVal clrType As Type) As Exception
        Return New ArgumentException("Unknown type: " & clrType.ToString())
    End Function

    Private Shared Function SqlMetaDataFromColumn(ByVal column As DataColumn, ByRef coerceToString As Boolean) As SqlMetaData
        coerceToString = False
        Dim sql_md As SqlMetaData = Nothing
        Dim clrType As Type = column.DataType
        Dim name As String = column.ColumnName
        Select Case Type.GetTypeCode(clrType)
            Case TypeCode.Boolean
                sql_md = New SqlMetaData(name, SqlDbType.Bit)
            Case TypeCode.Byte
                sql_md = New SqlMetaData(name, SqlDbType.TinyInt)
            Case TypeCode.Char
                sql_md = New SqlMetaData(name, SqlDbType.NVarChar, 1)
            Case TypeCode.DateTime
                sql_md = New SqlMetaData(name, SqlDbType.DateTime)
            Case TypeCode.DBNull
                Throw InvalidDataTypeCode(TypeCode.DBNull)
            Case TypeCode.Decimal
                sql_md = New SqlMetaData(name, SqlDbType.Decimal)
            Case TypeCode.Double
                sql_md = New SqlMetaData(name, SqlDbType.Float)
            Case TypeCode.Empty
                Throw InvalidDataTypeCode(TypeCode.Empty)
            Case TypeCode.Int16
                sql_md = New SqlMetaData(name, SqlDbType.SmallInt)
            Case TypeCode.Int32
                sql_md = New SqlMetaData(name, SqlDbType.Int)
            Case TypeCode.Int64
                sql_md = New SqlMetaData(name, SqlDbType.BigInt)
            Case TypeCode.SByte
                Throw InvalidDataTypeCode(TypeCode.SByte)
            Case TypeCode.Single
                sql_md = New SqlMetaData(name, SqlDbType.Real)
            Case TypeCode.String
                sql_md = New SqlMetaData(name, SqlDbType.NVarChar, column.MaxLength)
            Case TypeCode.UInt16
                Throw InvalidDataTypeCode(TypeCode.UInt16)
            Case TypeCode.UInt32
                Throw InvalidDataTypeCode(TypeCode.UInt32)
            Case TypeCode.UInt64
                Throw InvalidDataTypeCode(TypeCode.UInt64)
            Case TypeCode.Object
                sql_md = SqlMetaDataFromObjectColumn(name, column, clrType)
                If sql_md Is Nothing Then
                    ' Unknown type, try to treat it as string
                    sql_md = New SqlMetaData(name, SqlDbType.NVarChar, column.MaxLength)
                    coerceToString = True
                End If
            Case Else
                Throw UnknownDataType(clrType)
        End Select

        Return sql_md
    End Function

    Private Shared Function SqlMetaDataFromObjectColumn(ByVal name As String, ByVal column As DataColumn, ByVal clrType As Type) As SqlMetaData
        Dim sql_md As SqlMetaData = Nothing

        If (clrType Is GetType(System.Byte()) OrElse clrType Is GetType(SqlBinary) OrElse clrType Is GetType(SqlBytes) _
            OrElse clrType Is GetType(System.Char()) OrElse clrType Is GetType(SqlString) OrElse clrType Is GetType(SqlChars)) Then
            sql_md = New SqlMetaData(name, SqlDbType.VarBinary, column.MaxLength)
        ElseIf (clrType Is GetType(System.Guid)) Then
            sql_md = New SqlMetaData(name, SqlDbType.UniqueIdentifier)
        ElseIf (clrType Is GetType(System.Object)) Then
            sql_md = New SqlMetaData(name, SqlDbType.Variant)
        ElseIf (clrType Is GetType(SqlBoolean)) Then
            sql_md = New SqlMetaData(name, SqlDbType.Bit)
        ElseIf (clrType Is GetType(SqlByte)) Then
            sql_md = New SqlMetaData(name, SqlDbType.TinyInt)
        ElseIf (clrType Is GetType(SqlDateTime)) Then
            sql_md = New SqlMetaData(name, SqlDbType.DateTime)
        ElseIf (clrType Is GetType(SqlDouble)) Then
            sql_md = New SqlMetaData(name, SqlDbType.Float)
        ElseIf (clrType Is GetType(SqlGuid)) Then
            sql_md = New SqlMetaData(name, SqlDbType.UniqueIdentifier)
        ElseIf (clrType Is GetType(SqlInt16)) Then
            sql_md = New SqlMetaData(name, SqlDbType.SmallInt)
        ElseIf (clrType Is GetType(SqlInt32)) Then
            sql_md = New SqlMetaData(name, SqlDbType.Int)
        ElseIf (clrType Is GetType(SqlInt64)) Then
            sql_md = New SqlMetaData(name, SqlDbType.BigInt)
        ElseIf (clrType Is GetType(SqlMoney)) Then
            sql_md = New SqlMetaData(name, SqlDbType.Money)
        ElseIf (clrType Is GetType(SqlDecimal)) Then
            sql_md = New SqlMetaData(name, SqlDbType.Decimal, SqlDecimal.MaxPrecision, 0)
        ElseIf (clrType Is GetType(SqlSingle)) Then
            sql_md = New SqlMetaData(name, SqlDbType.Real)
        ElseIf (clrType Is GetType(SqlXml)) Then
            sql_md = New SqlMetaData(name, SqlDbType.Xml)
        Else
            sql_md = Nothing
        End If

        Return sql_md
    End Function
End Class

Public Class TestSendDataSet
    Private Const TestConnectionString As String = "context connection=true"
    Private Const prod1ID As Integer = 750  'Product ID of Road-150 Red, 44 bicycle
    Private Const prod2ID As Integer = 751  'Product ID of Road-150 Red, 48 bicycle

    ''' <summary>
    ''' Invoke a stored procedure to get some bill of material information and 
    ''' fill a data set with the two result sets.  Return the data set to the client.

    <SqlProcedure(Name:="usp_TestSendDataSet")> _
    Public Shared Sub DoTest()
        Dim conn As New SqlConnection(TestConnectionString)
        Try
            Dim cmd As SqlCommand = conn.CreateCommand()
            cmd.CommandText = "usp_GetTwoBOMTestData"
            cmd.CommandType = CommandType.StoredProcedure

            Dim prod1Param As New SqlParameter("@ProductID1", SqlDbType.Int)
            prod1Param.Value = prod1ID
            cmd.Parameters.Add(prod1Param)

            Dim prod2Param As New SqlParameter("@ProductID2", SqlDbType.Int)
            prod2Param.Value = prod2ID
            cmd.Parameters.Add(prod2Param)

            Dim asOfDateParam As New SqlParameter("@AsOfDate", SqlDbType.DateTime)
            asOfDateParam.Value = DateTime.Now
            cmd.Parameters.Add(asOfDateParam)

            Dim ds As New DataSet("TestData")
            Dim sda As New SqlDataAdapter(cmd)
            conn.Open()
            sda.Fill(ds)

            ' Normally, after filling the data set, rather than immediately returning it, 
            ' the data would be modified before invoking SendDataSet to deliver 
            ' the data within the data set as a result set to the client.  For simplicity 
            ' this sample simply returns the data.
            DataSetUtilities.SendDataSet(ds)
        Finally
            conn.Dispose()
        End Try
    End Sub
End Class

이는 어셈블리를 배포하고 저장 프로시저를 만드는 Transact-SQL 설치 스크립트(Install.sql)입니다.

USE AdventureWorks;
GO

IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'usp_GetTwoBOMTestData')
DROP PROCEDURE usp_GetTwoBOMTestData;
GO

IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'usp_TestSendDataSet')
DROP PROCEDURE usp_TestSendDataSet;
GO

IF EXISTS (SELECT * FROM sys.assemblies WHERE name = N'SendDataSet') 
DROP ASSEMBLY SendDataSet;
GO

-- Procedure used to generate test data to fill the data set being returned to the client
CREATE PROCEDURE usp_GetTwoBOMTestData
(
@ProductID1 int,
@ProductID2 int,
@AsOfDate DateTime
)
AS
BEGIN
EXEC uspGetBillOfMaterials @ProductID1, @AsOfDate;
EXEC uspGetBillOfMaterials @ProductID2, @AsOfDate;
END;
GO


DECLARE @SamplesPath nvarchar(1024)
-- You may need to modify the value of the this variable if you have installed the sample someplace other than the default location.
Set @SamplesPath = N'C:\MySample\'

CREATE ASSEMBLY SendDataSet from @SamplesPath +'SendDataSet.dll'
WITH PERMISSION_SET = Safe;
GO

CREATE PROCEDURE usp_TestSendDataSet
AS
EXTERNAL NAME [SendDataSet].[TestSendDataSet].[DoTest];
GO

이는 예제를 테스트하는 Transact-SQL 테스트 스크립트(test.sql)입니다.

USE AdventureWorks
GO

EXEC usp_TestSendDataSet
GO

다음 Transact-SQL은 데이터베이스에서 어셈블리 및 저장 프로시저를 제거합니다.

USE AdventureWorks
GO

IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'usp_GetTwoBOMTestData')
DROP PROCEDURE usp_GetTwoBOMTestData;
GO

IF EXISTS (SELECT * FROM sys.procedures WHERE name = N'usp_TestSendDataSet')
DROP PROCEDURE usp_TestSendDataSet;
GO

IF EXISTS (SELECT * FROM sys.assemblies WHERE name = N'SendDataSet') 
DROP ASSEMBLY SendDataSet;
GO

참고 항목

개념

CLR(공용 언어 런타임) 통합에 대한 사용 시나리오 및 예