首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么MS/PDO不能正确地推断偏移子句的参数类型?

为什么MS/PDO不能正确地推断偏移子句的参数类型?
EN

Stack Overflow用户
提问于 2022-10-10 13:04:38
回答 1查看 61关注 0票数 0

这段代码

代码语言:javascript
运行
复制
$stmt = db()->prepare('
    SELECT shoot, subject
    FROM photos
    ORDER BY shoot, subject
    OFFSET ? ROWS
    FETCH NEXT 100 ROWS ONLY
');
$stmt->execute([100]);
$photos = $stmt->fetchAll(PDO::FETCH_ASSOC);

产生此错误

PHP致命错误: Uncaught : SQLSTATE42000: MicrosoftSQL ServerThe为偏移子句提供的行数必须是整数。

如果我显式地转换为整数,它就能工作。

代码语言:javascript
运行
复制
$stmt = db()->prepare('
    SELECT shoot, subject
    FROM photos
    ORDER BY shoot, subject
    OFFSET CAST(? AS INTEGER) ROWS
    FETCH NEXT 100 ROWS ONLY
');
$stmt->execute([100]);
$photos = $stmt->fetchAll(PDO::FETCH_ASSOC);

据我所知,当您调用prepare()时,参数类型是“锁定”的,但是(正如错误所指示的)整数是这里唯一有意义的东西。大多数情况下,MS-SQL似乎能够推断参数类型。我很好奇为什么在这种情况下不能。

EN

Stack Overflow用户

回答已采纳

发布于 2022-10-10 14:54:45

通常,Server正在为您执行隐式转换。PDO (至少使用微软提供的驱动程序)将?作为字符串发送,除非您另有说明。通常作为nvarchar(4000),但有趣的是,它似乎依赖于您使用的第一个字符串。

XEvents显示这里的参数被发送为nvarchar(4000)

代码语言:javascript
运行
复制
$stmt = db()->prepare("
    SELECT CASE WHEN ? = 100 THEN 'OneHundred' ELSE 'SomethingElse' END AS example
");
$stmt->execute([100]);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);

不出所料,这个也被作为nvarchar(4000)发送。

代码语言:javascript
运行
复制
$stmt = db()->prepare("SELECT LEN(?) AS string_length_2");
$stmt->execute(['hi']);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);

更令人惊讶的是,这是作为nvarchar(max)发送的

代码语言:javascript
运行
复制
$stmt = db()->prepare("SELECT LEN(?) AS string_length_5000");
$stmt->execute([str_repeat('a', 5000)]);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);

当然,这就引出了一个问题:如果你先发送小数据,然后再发送大数据,那该怎么办:

代码语言:javascript
运行
复制
$stmt = db()->prepare("SELECT LEN(?) AS string_length");
$stmt->execute(['hi']);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);

$stmt->execute([str_repeat('a', 5000)]);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);

结果发现你犯了一个错误:

PHP致命错误:未指明的PDOException: SQLSTATE22001: MicrosoftString数据,C:\inetpub\wwwroot\photomgr\scratch.php:27中的右截断

好的,我们已经建立了PDO是猜测参数类型的方法,而且它做得不好。正如Rhythm是一个Lurker所指出的,解决方案是显式地指定一个类型:

代码语言:javascript
运行
复制
$stmt = db()->prepare("
    SELECT shoot, subject
    FROM photos
    ORDER BY shoot, subject
    OFFSET ? ROWS
    FETCH NEXT 100 ROWS ONLY
");
$stmt->bindValue(1, 100, PDO::PARAM_INT);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
var_dump($result);
票数 4
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74015427

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档