Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Platný pro
- Microsoft Ovladače verze 5.10.0 pro PHP a SQL Server
Úvod
Pomocí parametrů s hodnotou tabulky můžete odeslat více řádků dat do příkazu Transact-SQL nebo uložené procedury. Nemusíte vytvářet dočasnou tabulku. Pokud chcete použít parametr s hodnotami tabulky s ovladači PHP, deklarujte uživatelem definovaný typ tabulky s názvem, jak je znázorněno v příkladech na této stránce.
Použijte parametr tabulky s uloženou procedurou
Následující příklady předpokládají, že existují následující tabulky, typ tabulky a uložená procedura:
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
Ovladače PHP používají pro parametry s hodnotami tabulky (TVPs) vazbu s řádky a je nutné zadat název typu jako neprázdný řetězec. V tomto příkladu je název TVPParam. Vstup TVP je v podstatě dvojice klíč-hodnota, kde klíčem je název typu TVP a hodnotou jsou vstupní data ve formě vnořeného pole. Například:
$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(?, ?, ?, ?)}";
Použití ovladače SQLSRV
Můžete použít sqlsrv_query nebo sqlsrv_prepare s sqlsrv_execute. Následující příklad ukazuje první případ použití:
$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);
Kromě toho můžete použít sqlsrv_send_stream_data k odesílání dat TVP po spuštění. Například:
$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);
Použití ovladače PDO_SQLSRV
Toto je ekvivalentní příklad při použití ovladače PDO_SQLSRV. Můžete použít přípravu/spuštění s bindParam a zadat vstup TVP jako PDO::PARAM_LOB. Pokud ne, zobrazí se tato chyba: 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) {
...
}
Pokud uložená procedura přijímá pouze vstupní parametry, můžete místo bindParam použít bindValue.
Použít jiné schéma než výchozí schéma dbo
Pokud nepoužíváte výchozí schéma dbo, měli byste zadat název schématu. I když název schématu obsahuje znak mezery, nepoužívejte oddělovače jako [ nebo ].
$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);
Použití parametru s hodnotou tabulky bez uložené procedury
Parametry s hodnotou tabulky můžete použít bez uložených procedur. Představte si následující příklad:
CREATE TYPE id_table_type AS TABLE(id INT PRIMARY KEY)
CREATE TABLE test_table (id INT PRIMARY KEY)
Použití ovladače SQLSRV
Toto je příklad při použití uživatelem definovaného schématu:
$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);
Použití ovladače PDO_SQLSRV
Toto je příklad při použití výchozího schématu 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();