- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
prepare("SELEC-6ren">
我在 Ubuntu 14.04 LTS 上使用 PHP 5.5.9 和 MySQL 5.5.44 以及 mysqlnd 5.0.11-dev。以下语句无法准备:
$db->prepare("SELECT nr.x FROM (SELECT ? AS x) AS nr")
尽管以下语句已成功准备:
$db->prepare("SELECT nr.x FROM (SELECT '1337' AS x) AS nr")
造成这种差异的原因是什么? The manual说“参数标记只能用于数据值应该出现的地方,不能用于 SQL 关键字、标识符等。”但这是一个数据值。
同样的事情发生在独立客户端:
mysql -uredacted -predacted redacted
-- Type 'help;' or '\h' for help.
SELECT nr.x FROM (SELECT '1337' AS x) AS nr;
-- x
-- 1337
-- 1 row in set (0.00 sec)
PREPARE workingstmt FROM 'SELECT nr.x FROM (SELECT ''1337'' AS x) AS nr';
-- Query OK, 0 rows affected (0.00 sec)
-- Statement prepared
DEALLOCATE PREPARE workingstmt;
-- Query OK, 0 rows affected (0.00 sec)
PREPARE brokenstmt FROM 'SELECT nr.x FROM (SELECT ? AS x) AS nr';
-- ERROR 1054 (42S22): Unknown column 'nr.x' in 'field list'
^D
-- Bye
我正在尝试向具有自动递增主键的表中添加一行。在 InnoDB 默认的自增锁定模式下,the manual调用“连续”,InnoDB 在可能插入但未插入行时跳过自动增量值,就像 INSERT IGNORE
或 ON DUPLICATE KEY UPDATE
运行的情况一样到其 UNIQUE
值与要插入的行的值匹配的现有行中。 (这些在手册中称为“混合模式插入”。)
每隔几个小时,我就会从我的供应商那里导入一个提要。这有大约 200,000 行,这些行中除了平均 200 行之外的所有行都具有与表中已经存在的值相对应的唯一值。因此,如果我一直使用 INSERT IGNORE
或 ON DUPLICATE KEY UPDATE
,我每隔几个小时就会耗尽 199,800 个 ID。所以我不想使用 INSERT IGNORE
或 ON DUPLICATE KEY UPDATE
因为担心我可能会耗尽 INTEGER UNSIGNED
的 42 亿限制随着时间的推移重复插入到具有相同 UNIQUE
键的表。我不想将列切换为 BIGINT
类型,因为 32 位 PHP 没有与 MySQL BIGINT
具有相同语义的类型。服务器管理员不愿意切换到 64 位 PHP 或更改服务器所有用户的 innodb_autoinc_lock_mode
。
因此,我决定尝试 INSERT INTO ... SELECT
,在子查询中创建一个包含唯一键列的 1 行表,然后将其连接到主表以拒绝唯一键已经存在的值。 (手册上说 INSERT INTO ... SELECT
是一个“批量插入”,它不会烧掉 ID。)目的是做这样的事情:
INSERT INTO the_table
(uniquecol, othercol1, othercol2)
SELECT nr.uniquecol, :o1 AS othercol1, :o2 AS othercol2
FROM (
SELECT ? AS uniquecol
) AS nr
LEFT JOIN the_table ON nr.settlement_id = the_table.settlement_id
WHERE the_table.row_id IS NULL
这失败了,给出了 PDO 错误:["42S22",1054,"'字段列表'中的未知列'settlement_id'"]
<?php // MCVE follows
/* Connect to database */
$pdo_dsn = 'mysql:host=127.0.0.1;dbname=redacted';
$pdo_username = 'redacted';
$pdo_password = 'redacted';
$pdo_options = [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',];
$db = new PDO($pdo_dsn, $pdo_username, $pdo_password, $pdo_options);
$pdo_dsn = $pdo_username = $pdo_password = 'try harder';
// ensure that PDO doesn't convert everything to strings
// per http://stackoverflow.com/a/15592818/2738262
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
/* Create mock data with which to test the statements */
$prep_stmts = ["
CREATE TEMPORARY TABLE sotemp (
file_id INTEGER UNSIGNED PRIMARY KEY AUTO_INCREMENT,
settlement_id VARCHAR(30) NOT NULL,
num_lines INTEGER UNSIGNED NOT NULL DEFAULT 0,
UNIQUE (settlement_id)
)
","
INSERT INTO sotemp (settlement_id, num_lines) VALUES
('15A1', 150),
('15A2', 273),
('15A3', 201)
"];
foreach ($prep_stmts as $stmt) $db->exec($stmt);
/* Now the tests */
$working_stmt = $db->prepare("
SELECT nr.settlement_id
FROM (
-- change this to either a value in sotemp or one not in sotemp
-- and re-run the test program
SELECT '15A3' AS settlement_id
) AS nr
LEFT JOIN sotemp ON nr.settlement_id = sotemp.settlement_id
WHERE sotemp.file_id IS NULL
");
if ($working_stmt) {
$working_stmt->execute();
$data = $working_stmt->fetchAll(PDO::FETCH_ASSOC);
echo "Working: ".json_encode($data)."\n";
} else {
echo "Working statement failed: ".json_encode($db->errorInfo())."\n";
}
$broken_stmt = $db->prepare("
SELECT nr.settlement_id
FROM (
SELECT ? AS settlement_id
) AS nr
LEFT JOIN sotemp ON nr.settlement_id = sotemp.settlement_id
WHERE sotemp.file_id IS NULL
");
if ($broken_stmt) {
$broken_stmt->execute(['15A4']);
$data = $broken_stmt->fetchAll(PDO::FETCH_ASSOC);
echo "Broken: ".json_encode($data)."\n";
} else {
echo "Broken statement failed: ".json_encode($db->errorInfo())."\n";
}
是什么导致了这个错误?有没有更好的方法,只在主键不存在的情况下插入一行而不用尽自增ID?
最佳答案
您最近的编辑使问题非常清楚,所以我会尝试回答:造成这种差异的原因是占位符。
记录在案here , 占位符只能在查询中的某些地方使用。特别是:
Parameter markers can be used only where data values should appear, not for SQL keywords, identifiers, and so forth.
现在您可能已经注意到 SELECT ? as x
准备得很好,但不是 SELECT nr.x FROM (SELECT ? AS x) AS nr
。这是为什么?嗯,这最好用 an anonymous author on PHP's doc 来解释。 ,所以让我复制/粘贴:
There is a common misconception about how the placeholders in prepared statements work: they are not simply substituted in as (escaped) strings, and the resulting SQL executed. Instead, a DBMS asked to "prepare" a statement comes up with a complete query plan for how it would execute that query, including which tables and indexes it would use, which will be the same regardless of how you fill in the placeholders.
简单地说:因为你在FROM
子句中的子查询中使用了占位符,所以MySQL无法计算查询的执行计划。
换句话说,由于您的查询总是会发生变化,因此没有可以为其准备的"template"。
因此如果你真的想使用这个查询,你需要使用一个普通的(非准备好的)查询,或者重新打开 PDO 的模拟准备语句。
话虽如此,请务必考虑评论部分提供的各种替代方案。对于您要实现的目标,有更好的解决方案。
关于php - "Unknown column in ' 字段列表 '"当准备语句的占位符在子查询中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32124682/
我尝试使用以下 json,但 wiremock 无法识别我的更改。我看了wiremock的文档,看到他们说:JSON相等匹配是基于JsonUnit的,因此支持占位符。我也尝试使用 JDK 8 和 JD
我发现这种方法可以使用 mixin 轻松添加 @media block : @mixin phone() { @media only screen and (max-width: 480px)
我有四个依赖的选择列表,我想给所有选择列表一个默认值/占位符,如下所示:select ... 。问题是,当我尝试这样做时: Select ... 它不起作用。因为当我更改第一个选择列表时,其他选择列表
所以我只是浏览我们的库存管理系统的代码我看到了我一位同事的一些片段,他在某些功能中所做的只是例如,只需打开它们并在其中插入命令 procedure TWerkStF.TBBtnStatiClick(S
因此,对于我当前的 Bukkit(Minecraft)插件,我必须使用 ItemStacks 的名称。我通过这样做得到这些名字 item.getItemMeta().getDisplayName();
我想为 JAVA 开发一个猜词游戏,但在开发 GUI 时遇到了一些困难。我并不是想开发一个仅使用一个文本字段的简单 GUI,我想开发一个更像移动设备的 GUI。因此,我希望白框显示为单词中字符的占位符
我想测试输出是否如下所示: String s1 = "You have 5 Dollar in your bank account." 要通过测试,字符串需要相等,所以我需要一个相等的字符串: Str
已关闭。这个问题是 off-topic 。目前不接受答案。 想要改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 已关闭11 年前。 Improve th
我一直在使用 JavaScript 占位符脚本来支持 IE 占位符。 适用于输入类型 = 文本。但是我该如何在脚本中添加一个支持 textarea 的内容呢? 我的代码是: function acti
我正在寻找一个正则表达式,它可以正确检测字符串中是否存在 printf() 类型的占位符。 最佳答案 事实证明这比看起来要复杂一些,答案取决于您想对占位符做什么,以及您对 printf 和正则表达式使
注意占位符在 Stackoverflow 提问标题和 Twitter 注册表单上的工作方式:https://twitter.com/signup 占位符有两种状态: 未选择(显示占位符) 已选择,但有
我想将"template"文件的输出通过管道传输到 MySQL,该文件散布着 ${dbName} 等变量。替换这些实例并将输出转储到标准输出的命令行实用程序是什么? 输入文件被认为是安全的,但可能存在
我有一个像这样的js数组: let data = [{status:"stay",points:[1,2,3,4,5]}, {status:"move",points:[1,2,3,4,5]},{st
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Show default value for editing on Python input possible? 我
我正在尝试使用 python format 方法将我的占位符格式化为字符串。 问题是字符串内部包含 {} 并且字符串方法无法解析它。 my_value='v' '{"k":"{value}"}'.fo
我正在使用 PHP + CodeIgniter 构建一个多语言应用程序。我决定使用 gettext 进行 UI 文本翻译,到目前为止,它已被证明高效且易于使用。 但现在我遇到了一些非常烦人的事情:ge
我有一个 NSAttributedString 看起来像 “一些字符串 bold %@ template %f %d blah blah blah” 我希望能够像 [NSString stringWi
我喜欢偶尔为占位符使用空函数(主要是空构造函数,因为它有助于避免构造函数的意外重复,因为我的团队知道必须始终有一个构造函数)。 我还喜欢对一个类的每个方法至少进行一次测试(主要是因为这是一个很好的简单
我正在尝试向 Angular 4 上的选择添加占位符,但无法使其正常工作, 这是我的代码: Please select one option {{ select
有没有办法在 sqlite3 中设置查询的占位符?我有一些与数据库一起工作的函数,如果它们可以同时与 mysql 和 sqlite 一起工作,那就更令人满意了。Mysql 和 Postgres pyt
我是一名优秀的程序员,十分优秀!