다음을 통해 공유


테이블 반환 매개 변수 사용(PHP)

PHP 드라이버 다운로드

적용 가능 대상

  • Microsoft Drivers 5.10.0 for PHP for SQL Server

소개

테이블 반환 매개 변수를 사용하여 여러 행의 데이터를 Transact-SQL 문 또는 저장 프로시저로 보낼 수 있습니다. 임시 테이블은 만들 필요가 없습니다. PHP 드라이버에 테이블 반환 매개 변수를 사용하려면 이 페이지의 예제와 같이 이름이 지정된 사용자 정의 테이블 형식을 선언합니다.

저장 프로시저에 테이블 반환 매개 변수 사용

다음 예제에서는 다음과 같은 테이블, 테이블 형식, 저장 프로시저가 있다고 가정해 보세요:

CREATE TABLE TVPOrd(
    OrdNo INTEGER IDENTITY(1,1),
    OrdDate DATETIME,
    CustID VARCHAR(10))


CREATE TABLE TVPItem(
    OrdNo INTEGER,
    ItemNo INTEGER IDENTITY(1,1),
    ProductCode CHAR(10),
    OrderQty INTEGER,
    SalesDate DATE,
    Label NVARCHAR(30),
    Price DECIMAL(5,2),
    Photo VARBINARY(MAX))


--Create TABLE type for use as a TVP
CREATE TYPE TVPParam AS TABLE(
                ProductCode CHAR(10),
                OrderQty INTEGER,
                SalesDate DATE,
                Label NVARCHAR(30),
                Price DECIMAL(5,2),
                Photo VARBINARY(MAX))


--Create procedure with TVP parameters
CREATE PROCEDURE TVPOrderEntry(
        @CustID VARCHAR(10),
        @Items TVPParam READONLY,
        @OrdNo INTEGER OUTPUT,
        @OrdDate DATETIME OUTPUT)
AS
BEGIN
    SET @OrdDate = GETDATE(); SET NOCOUNT ON;
    INSERT INTO TVPOrd (OrdDate, CustID) VALUES (@OrdDate, @CustID);
    SELECT @OrdNo = SCOPE_IDENTITY();
    INSERT INTO TVPItem (OrdNo, ProductCode, OrderQty, SalesDate, Label, Price, Photo)
    SELECT @OrdNo, ProductCode, OrderQty, SalesDate, Label, Price, Photo
    FROM @Items
END

PHP 드라이버는 TVP(테이블 반환 매개 변수)에 행 단위 바인딩을 사용하며 형식 이름을 비어 있지 않은 문자열로 제공해야 합니다. 이 예제에서 이름은 TVPParam입니다. TVP 입력은 기본적으로 TVP 형식 이름을 키로 사용하고 입력 데이터를 중첩된 배열로 사용하는 키-값 쌍입니다. 예시:

$image1 = fopen($pic1, 'rb');
$image2 = fopen($pic2, 'rb');
$image3 = fopen($pic3, 'rb');

$items = [
    ['0062836700', 367, "2009-03-12", 'AWC Tee Male Shirt', '20.75', $image1],
    ['1250153272', 256, "2017-11-07", 'Superlight Black Bicycle', '998.45', $image2],
    ['1328781505', 260, "2010-03-03", 'Silver Chain for Bikes', '88.98', $image3],
];

// Create a TVP input array
$tvpType = 'TVPParam';
$tvpInput = array($tvpType => $items);

// To execute the stored procedure, either execute a direct query or prepare this query:
$callTVPOrderEntry = "{call TVPOrderEntry(?, ?, ?, ?)}";

SQLSRV 드라이버 사용

sqlsrv_execute를 사용하여 sqlsrv_query 또는 sqlsrv_prepare를 호출할 수 있습니다. 다음 예제에서는 이전 사용 사례를 보여 줍니다:

$custCode = 'SRV_123';
$ordNo = 0;
$ordDate = null;
$params = array($custCode,
                array($tvpInput, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_TABLE, SQLSRV_SQLTYPE_TABLE), // or simply array($tvpInput),
                array(&$ordNo, SQLSRV_PARAM_OUT),
                array(&$ordDate, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR)));
$stmt = sqlsrv_query($conn, $callTVPOrderEntry, $params);
if (!$stmt) {
    print_r(sqlsrv_errors());
}
sqlsrv_next_result($stmt);

또한 sqlsrv_send_stream_data를 사용하여 실행 후 TVP 데이터를 보낼 수 있습니다. 예시:

$options = array("SendStreamParamsAtExec" => 0);
$stmt = sqlsrv_prepare($conn, $callTVPOrderEntry, $params, $options);
if (!$stmt) {
    print_r(sqlsrv_errors());
}
$res = sqlsrv_execute($stmt);
if (!$res) {
    print_r(sqlsrv_errors());
}

// Now call sqlsrv_send_stream_data in a loop
while (sqlsrv_send_stream_data($stmt)) {
}
sqlsrv_next_result($stmt);

PDO_SQLSRV 드라이버 사용

PDO_SQLSRV 드라이버를 사용하는 경우와 동일한 예제입니다. bindParam에 prepare/execute를 사용하고 TVP 입력을 PDO::PARAM_LOB로 지정할 수 있습니다. 그렇지 않으면 Operand type clash: nvarchar is incompatible with … 오류가 발생합니다.

try {
    $stmt = $conn->prepare($callTVPOrderEntry);
    $stmt->bindParam(1, $custCode);
    $stmt->bindParam(2, $tvpInput, PDO::PARAM_LOB);
    // 3 - OrdNo output
    $stmt->bindParam(3, $ordNo, PDO::PARAM_INT, 10);
    // 4 - OrdDate output
    $stmt->bindParam(4, $ordDate, PDO::PARAM_STR, 20);
    $stmt->execute();
} catch (PDOException $e) {
    ...
}

저장 프로시저에서 입력 매개 변수만 사용하는 경우 bindParam 대신 bindValue를 사용할 수 있습니다.

기본 dbo 스키마 이외의 스키마 사용

기본 dbo 스키마를 사용하지 않는 경우 스키마 이름을 입력해야 합니다. 스키마 이름에 공백 문자가 포함되어 있더라도 [ 또는 ] 같은 구분 기호를 사용하지 마세요.

    $inputs = [
        ['ABC', 12345, null],
        ['DEF', 6789, 'This is a test']
    ];
    $schema = 'Sales DB';
    $tvpType = 'TestTVP';

    // i.e. the TVP type name is "[Sales DB].[TestTVP]"
    $tvpInput = array($tvpType => $inputs, $schema);

저장 프로시저 없이 테이블 반환 매개 변수 사용

저장 프로시저 없이 테이블 반환 매개 변수를 사용할 수 있습니다. 다음 예제를 참조해 주세요:

CREATE TYPE id_table_type AS TABLE(id INT PRIMARY KEY)

CREATE TABLE test_table (id INT PRIMARY KEY)

SQLSRV 드라이버 사용

다음은 사용자 정의 스키마를 사용하는 예제입니다:

$schema = 'my schema';
$tvpName = 'id_table_type';

$tsql = "INSERT INTO [$schema].[test_table] SELECT * FROM ?";
$params = [
[[$tvpname => [[1], [2], [3]], $schema]],
];

$stmt = sqlsrv_query($conn, $tsql, $params);
if (!$stmt) {
    print_r(sqlsrv_errors());
}
sqlsrv_free_stmt($stmt);

PDO_SQLSRV 드라이버 사용

다음은 기본 dbo 스키마를 사용하는 예제입니다:

$tsql = "INSERT INTO test_table SELECT * FROM ?";
$tvpInput = array('id_table_type' => [[1], [2], [3]]);

$stmt = $conn->prepare($tsql);
$stmt->bindParam(1, $tvpInput, PDO::PARAM_LOB);
$result = $stmt->execute();

또한 참고해 주세요