Aracılığıyla paylaş


Tablo değerli parametreleri kullanma (PHP)

PHP sürücüsünü indirme

Geçerli olan

  • SQL Server için PHP için Microsoft Drivers 5.10.0

Giriş

Tablo değerli parametreleri kullanarak bir Transact-SQL deyimine veya saklı yordama birden çok veri satırı gönderebilirsiniz. Geçici bir tablo oluşturmanız gerekmez. PHP sürücüleriyle tablo değerli bir parametre kullanmak için, bu sayfadaki örneklerde gösterildiği gibi adlandırılmış bir kullanıcı tanımlı tablo türü tanımlayın.

Tablo değerli bir parametre ile saklı yordam kullanma

Aşağıdaki örneklerde aşağıdaki tabloların, tablo türünün ve saklı yordamın mevcut olduğu varsayılır:

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 sürücüleri tablo değerli parametreler (TVP' ler) için satır başına bağlama kullanır ve tür adını boş olmayan bir dize olarak sağlamanız gerekir. Bu örnekte adı şeklindedir TVPParam. TVP girişi, temelde TVP türü adının anahtar ve giriş verilerinin iç içe geçmiş bir dizi olduğu bir anahtar-değer çiftidir. Örneğin:

$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 sürücüsünü kullanma

sqlsrv_query veya sqlsrv_execute ile sqlsrv_prepare arayabilirsiniz. Aşağıdaki örnek, önceki kullanım örneğini gösterir:

$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);

Ayrıca, yürütme sonrasında TVP verilerini göndermek için sqlsrv_send_stream_data kullanabilirsiniz. Örneğin:

$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 sürücüsünü kullanma

Bu, PDO_SQLSRV sürücüsünü kullanırken eşdeğer bir örnektir. bindParam ile hazırlama/yürütme özelliğini kullanabilir ve TVP girişini olarak PDO::PARAM_LOBbelirtebilirsiniz. Aksi takdirde şu hatayı alırsınız: 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) {
    ...
}

Saklı yordamınız yalnızca giriş parametreleri alıyorsa bindParam yerine bindValue kullanabilirsiniz.

Varsayılan dbo şeması dışında bir şema kullanma

Varsayılan dbo şemasını kullanmıyorsanız şema adını sağlamanız gerekir. Şema adında boşluk karakteri olsa bile veya [gibi ] sınırlayıcıları kullanmayın.

    $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);

Saklı prosedür kullanmadan tablolu parametre kullanma

Saklı yordamlar olmadan tablo değerine sahip parametreler kullanabilirsiniz. Aşağıdaki örneği inceleyin:

CREATE TYPE id_table_type AS TABLE(id INT PRIMARY KEY)

CREATE TABLE test_table (id INT PRIMARY KEY)

SQLSRV sürücüsünü kullanma

Bu, kullanıcı tanımlı bir şema kullanılırken bir örnektir:

$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 sürücüsünü kullanma

Bu, varsayılan dbo şemasını kullanırken bir örnektir:

$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();

Ayrıca bakınız