Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Berlaku untuk
- Driver Microsoft 5.10.0 untuk PHP pada SQL Server
Pendahuluan
Anda dapat menggunakan parameter bernilai tabel untuk mengirim beberapa baris data ke pernyataan Transact-SQL atau prosedur tersimpan. Anda tidak perlu membuat tabel sementara. Untuk menggunakan parameter bernilai tabel dengan driver PHP, deklarasikan jenis tabel yang ditentukan pengguna dengan nama, seperti yang ditunjukkan dalam contoh di halaman ini.
Gunakan parameter bernilai tabel dengan prosedur tersimpan
Contoh berikut mengasumsikan tabel, jenis tabel, dan prosedur tersimpan berikut ini ada:
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
driver PHP menggunakan pengikatan per baris untuk parameter bernilai tabel (TVP), dan Anda harus memberikan nama tipe dalam bentuk string yang tidak kosong. Dalam contoh ini, namanya adalah TVPParam. Input TVP pada dasarnya merupakan pasangan kunci-nilai dengan nama tipe TVP sebagai kunci dan data input sebagai larik bertingkat. Contohnya:
$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(?, ?, ?, ?)}";
Menggunakan driver SQLSRV
Anda dapat memanggil sqlsrv_query atau sqlsrv_prepare dengan sqlsrv_execute. Contoh berikut menunjukkan kasus penggunaan sebelumnya:
$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);
Selain itu, Anda dapat menggunakan sqlsrv_send_stream_data untuk mengirim data TVP setelah eksekusi. Contohnya:
$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);
Gunakan driver PDO_SQLSRV
Ini adalah contoh yang setara saat menggunakan driver PDO_SQLSRV. Anda dapat menggunakan persiapan/eksekusi dengan bindParam dan menentukan input TVP sebagai PDO::PARAM_LOB. Jika tidak, Anda akan mendapatkan kesalahan ini: 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) {
...
}
Jika prosedur tersimpan hanya mengambil parameter input, Anda dapat menggunakan bindValue alih-alih bindParam.
Menggunakan skema selain skema dbo default
Jika Anda tidak menggunakan skema dbo default, maka Anda harus memberikan nama skema. Bahkan jika nama skema berisi karakter spasi, jangan gunakan pemisah seperti [ atau ].
$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);
Gunakan parameter bernilai tabel tanpa prosedur tersimpan
Anda dapat menggunakan parameter bernilai tabel tanpa prosedur tersimpan. Pertimbangkan contoh berikut:
CREATE TYPE id_table_type AS TABLE(id INT PRIMARY KEY)
CREATE TABLE test_table (id INT PRIMARY KEY)
Menggunakan driver SQLSRV
Ini adalah contoh saat menggunakan skema yang ditentukan pengguna:
$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);
Gunakan driver PDO_SQLSRV
Ini adalah contoh saat menggunakan skema dbo default:
$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();