Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of mappen te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen om mappen te wijzigen.
Van toepassing op
- Microsoft Drivers 5.10.0 voor PHP voor SQL Server
Introductie
U kunt parameters met tabelwaarden gebruiken om meerdere rijen met gegevens te verzenden naar een Transact-SQL-instructie of een opgeslagen procedure. U hoeft geen tijdelijke tabel te maken. Als u een tabelwaardeparameter wilt gebruiken met de PHP-stuurprogramma's, declareert u een door de gebruiker gedefinieerd tabeltype met een naam, zoals wordt weergegeven in de voorbeelden op deze pagina.
Een parameter met tabelwaarde gebruiken met een opgeslagen procedure
In de volgende voorbeelden wordt ervan uitgegaan dat de volgende tabellen, het tabeltype en de opgeslagen procedure bestaan:
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
De PHP-stuurprogramma's gebruiken rijgebonden binding voor parameters met tabelwaarde (TVP's) en u moet de typenaam opgeven als een niet-lege tekenreeks. In dit voorbeeld is TVPParam de naam. De TVP-invoer is in feite een sleutel-waardepaar met de naam van het TVP-type als de sleutel en de invoergegevens als een geneste matrix. Voorbeeld:
$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(?, ?, ?, ?)}";
Het SQLSRV-stuurprogramma gebruiken
U kunt sqlsrv_query of sqlsrv_prepare bellen met sqlsrv_execute. In het volgende voorbeeld ziet u de voormalige use case:
$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);
Daarnaast kunt u sqlsrv_send_stream_data gebruiken om TVP-gegevens na de uitvoering te verzenden. Voorbeeld:
$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);
Het stuurprogramma PDO_SQLSRV gebruiken
Dit is een gelijkwaardig voorbeeld wanneer u het PDO_SQLSRV stuurprogramma gebruikt. U kunt prepare/execute gebruiken met bindParam en de TVP-invoer opgeven als een PDO::PARAM_LOB. Zo niet, dan krijgt u de volgende fout: 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) {
...
}
Als uw opgeslagen procedure alleen invoerparameters gebruikt, kunt u bindValue gebruiken in plaats van bindParam.
Een ander schema dan het standaard-dbo-schema gebruiken
Als u het standaard-dbo-schema niet gebruikt, moet u de schemanaam opgeven. Zelfs als de schemanaam een spatieteken bevat, gebruikt u geen scheidingstekens zoals [ of ].
$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);
Een tabelwaardeparameter gebruiken zonder een opgeslagen procedure
U kunt parameters met tabelwaarden gebruiken zonder opgeslagen procedures. Bekijk het volgende voorbeeld:
CREATE TYPE id_table_type AS TABLE(id INT PRIMARY KEY)
CREATE TABLE test_table (id INT PRIMARY KEY)
Het SQLSRV-stuurprogramma gebruiken
Dit is een voorbeeld wanneer u een door de gebruiker gedefinieerd schema gebruikt:
$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);
Het stuurprogramma PDO_SQLSRV gebruiken
Dit is een voorbeeld wanneer u het standaard dbo-schema gebruikt:
$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();