insert into table1(id, text) select (max(id)+1), "Something" from table1
如何使用SQL::抽象或SQL::抽象::More生成此查询?
发布于 2013-04-17 03:06:20
您可以这样做:
use strict;
use warnings;
use SQL::Abstract;
my $sa = SQL::Abstract->new;
my $select = $sa->select('table1', "MAX(id) + 1, 'Something'");
my $full_sql = "INSERT INTO table1 (id, text) $select";但说真的,你为什么要这么做呢?您的示例很简单,正如其他人所指出的那样,最好只编写SQL。如果你想让“某物”成为一个变量,你可以这样做:
my $new_id = $sa->select('table1', 'MAX(id) + 1');
my $data = {
id => \["($new_id)"],
text => $some_value_from_elsewhere
};
my ($sql, @binds) = $sa->insert('table1', $data);发布于 2013-04-12 22:09:04
正如Rachcha指出的那样,您的SQL语句包含一些缺陷。我假设你在尝试像这样的东西
insert into table1(id, text) values((select (max(id)+1) from table1), "Something")如果您想将新数据添加到具有唯一ID的table1中,那么您真的应该考虑在数据库的id字段中添加一个主键。
已更新答案
旧的anwser 确实创建了一个关于数据和语法的有效SQL语句,但是DBI中的准备和执行函数对这些值进行了一些魔术处理。
如果我像这样运行查询:
my $query = "insert into table1 values((select (max(id)+1) from table1), 'Something')";
$dbh->do($query);查询在执行时将保持原样。当我改为使用prepare和execute时,DBI会自动将值放在单引号之间,如'this‘,这会导致:
insert into table1(id, text) values('(select (max(id)+1) from table1)', 'Something');显然,这会将值打印为文本(如果这是有效的数据类型)。在我看来,这并不意味着从代码生成的查询是错误的,而不是来自DBI的不需要的引用。我找不到能不能去掉它们的答案。问题是如果DBI支持insert ...select语句。否则,您将无法对这些查询使用SQL::Abstract (或准备/执行)。
您可以将其构建为两步火箭,只要您的数据库没有多个事务,这可能会导致重复。
my $select_stmt = $sql->select('table1', '(max(id)+1)'):
# Prepare with $stmt
# Fetch your result and declare $max_id, e.g.
my $sth = $dbh->prepare($select_stmt);
$sth->execute();
my $max_id = 0;
my @max_id_arr = $sth->fetchrow_array();
$max_id = $max_id_arr[0];
die($max_id . " is 0") unless($max_id);
my %data = (
id => $max_id,
text => 'Something',
);
my($insert_stmt, @insert_bind) = $sql->insert('table1', \%data);旧答案
然而,为了回答你的问题,这应该能起到作用:
my $max_id = $sql->select('table1', 'max(id)+1');
my %data = (
id => "($max_id)",
text => "Something",
);
my($stmt, @bind) = $sql->insert('table1', \%data);
printf("My SQL statement was %s\nThe values was %s\n", $insert_stmt, join(", ", @insert_bind));这将打印出来
我的
语句是INSERT INSERT到table1 ( id,text)值( ?,?)值是(SELECT max(id)+1 FROM table1),即
发布于 2013-04-16 19:51:07
虽然我在我的代码中使用了很多SQL::Abstract,但我不建议在您的示例中使用它。主要是因为如果您直接编写SQL-Code,它有时会更具可读性和可维护性。因为您必须确保插入字段的顺序与选择字段的顺序完全匹配。
但是,如果有必要,您可以使用$sql->where()方法从select查询中提取where部分:
my $stmt1 = <<'END_SQL';
INSERT INTO table1(id, text)
SELECT (MAX(id)+1) id, 'Something' text
FROM table1
END_SQL
my ($stmt2,@binds) = $sql->where( key1=>$value1, key2=>$value2 );然后简单地连接这两个SQL语句。
https://stackoverflow.com/questions/15900230
复制相似问题