如果我理解正确,我正在使用以下堆栈:PHP< - > PDO< - > MS SQL DBLIB< - > freetds< - > MS SQL Server。
$pdo = new \PDO('dblib:host=192.168.0.10:1433;dbname=MyDb;charset=UTF-8', 'mydb', 'secret', [
\PDO::ATTR_CASE => \PDO::CASE_NATURAL,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_ORACLE_NULLS => \PDO::NULL_NATURAL,
\PDO::ATTR_STRINGIFY_FETCHES => false,
]);
$statement = $pdo->prepare("EXEC [dbo].[sp_MyStoredProcedure] 1, 2, 3");
if ( ! $statement->execute()) {
throw new \ErrorException('Error executing sp_MyStoredProcedure');
}
$data = $statement->fetchAll(\PDO::FETCH_ASSOC);
我将ERRMODE
设置为ERRMODE_EXCEPTION
,并且存储过程中发生 515 错误,但没有抛出异常,为什么? $data
正在存储空数组,我认为这是执行存储过程的正确结果。为了解决这个问题,我添加了检查$statement->errorInfo()[1]
,因为我不确定以这种方式检查错误是否合适:
if ( ! $statement->execute() || $statement->errorInfo()[1]) {
throw new \ErrorException('Error executing sp_MyStoredProcedure');
}
我是否正确地进行了这项检查?
详细的$ statement-> errorInfo():
array (
0 => '00000',
1 => 515,
2 => 'General SQL Server error: Check messages from the SQL Server [515] (severity 16) [(null)]',
3 => -1,
4 => 16,
)
另外根据article错误 515 是将NULL插入到非NULL的列中的错误。但是为什么我在Microsoft SQL Server Management Studio或tsql(freetds-bin)中执行EXEC [dbo].[sp_MyStoredProcedure] 1, 2, 3
时没有看到此错误?
答案 0 :(得分:1)
我遇到了类似的问题。
解决方案 - 为存储过程中的临时表列显式指定null-ability。
在:
create table #resultsTable(
paging_id int,
pt_key bigint,
pt_ctkeyfrom int
)
后:
create table #resultsTable(
paging_id int NULL,
pt_key bigint NULL,
pt_ctkeyfrom int NULL
)
对我来说问题已经解决了。
不幸的是,我不知道如何在不改变程序代码的情况下解决。
答案 1 :(得分:-1)
要查看您的异常,您需要在抛出它们时捕获它们。您的代码不会监听PDOException
,因为您错过了try-catch
语句。
以下是处理抛出异常的方法时的错误检查示例:
$pdo = null;
try {
$pdo = new \PDO('dblib:host=192.168.0.10:1433;dbname=MyDb;charset=UTF-8', 'mydb', 'secret', [
\PDO::ATTR_CASE => \PDO::CASE_NATURAL,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_ORACLE_NULLS => \PDO::NULL_NATURAL,
\PDO::ATTR_STRINGIFY_FETCHES => false,
]);
$statement = $pdo->prepare("EXEC [dbo].[sp_MyStoredProcedure] 1, 2, 3");
$data = $statement->fetchAll(\PDO::FETCH_ASSOC);
}
catch( PDOException $e ) {
print_r( $pdo->errorInfo() ); // PDO::errorInfo() returns an array
// [0] : sql error code
// [1] : driver error code
// [2] : error message
}
您看到您不必抛出任何自定义异常,您必须相对于其性质捕获它们(PDO抛出PDOException
)。
您最终可能会抛出自己的异常,但是您需要在另一段代码中捕获它们。这是一个适合您原始代码的示例:
$pdo = null;
try {
$pdo = new \PDO('dblib:host=192.168.0.10:1433;dbname=MyDb;charset=UTF-8', 'mydb', 'secret', [
\PDO::ATTR_CASE => \PDO::CASE_NATURAL,
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_ORACLE_NULLS => \PDO::NULL_NATURAL,
\PDO::ATTR_STRINGIFY_FETCHES => false,
]);
$statement = $pdo->prepare("EXEC [dbo].[sp_MyStoredProcedure] 1, 2, 3");
if ( ! $statement->execute()) {
throw new \ErrorException('Error executing sp_MyStoredProcedure');
}
$data = $statement->fetchAll(\PDO::FETCH_ASSOC);
}
catch( PDOException $e ) {
print_r( $pdo->errorInfo() ); // PDO::errorInfo() returns an array
// [0] : sql error code
// [1] : driver error code
// [2] : error message
}
catch( ErrorException $e ) {
print_r( $e );
}