Sql 抽象生成插入与选择查询

Sql 抽象生成插入与选择查询,sql,perl,sqlite,sql-generation,Sql,Perl,Sqlite,Sql Generation,插入到table1id中,文本选择maxid+1,表1中的内容 如何使用SQL::Abstract或SQL::Abstract::More生成此查询?正如Rachcha指出的,您的SQL语句包含一些缺陷。我猜你是在尝试类似的事情 insert into table1(id, text) values((select (max(id)+1) from table1), "Something") 如果你想用唯一的ID在表1中添加新的数据,你真的应该考虑在数据库中添加一个主键到你的ID字段。< /P

插入到table1id中,文本选择maxid+1,表1中的内容


如何使用SQL::Abstract或SQL::Abstract::More生成此查询?

正如Rachcha指出的,您的SQL语句包含一些缺陷。我猜你是在尝试类似的事情

insert into table1(id, text) values((select (max(id)+1) from table1), "Something")

如果你想用唯一的ID在表1中添加新的数据,你真的应该考虑在数据库中添加一个主键到你的ID字段。< /P> 最新答案

旧的anwser确实创建了一个关于数据和语法的有效SQL语句,但是DBI中的prepare和execute函数对这些值进行了一些处理

如果我像这样运行查询:

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是否支持插入。。。选择所有语句。否则,您将无法使用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));
这会打印出来

我的SQL语句被插入到table1 id,文本值? 这些值是从表1中选择maxid+1


正如Rachcha指出的,您的SQL语句包含一些缺陷。我猜你是在尝试类似的事情

insert into table1(id, text) values((select (max(id)+1) from table1), "Something")

如果你想用唯一的ID在表1中添加新的数据,你真的应该考虑在数据库中添加一个主键到你的ID字段。< /P> 最新答案

旧的anwser确实创建了一个关于数据和语法的有效SQL语句,但是DBI中的prepare和execute函数对这些值进行了一些处理

如果我像这样运行查询:

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是否支持插入。。。选择所有语句。否则,您将无法使用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));
这会打印出来

我的SQL语句被插入到table1 id,文本值? 这些值是从表1中选择maxid+1


虽然我在代码中经常使用SQL::Abstract,但我不建议在您的示例中使用它。主要是因为如果您直接编写SQL代码,它有时更具可读性和可维护性。因为您必须确保插入字段的顺序与选择字段的顺序完全匹配

但是,如果必须执行以下操作,您可以使用$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语句。

虽然我在代码中经常使用SQL::Abstract,但我不建议在您的示例中使用它。主要是因为如果您直接编写SQL代码,它有时更具可读性和可维护性。因为您必须确保插入字段的顺序与选择字段的顺序完全匹配

但是,如果必须执行以下操作,您可以使用$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语句。

您可以这样做:

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);
您可以这样做:

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);

你能解释一下你试过什么吗?您的SQL语句中存在一些基本缺陷。我只想了解如何使用SQL::Abstract或SQL::Abstract::More进行一些复杂的查询。我知道这个声明中有一些缺陷,比如我刚得到的。文档不够好@koriander你是对的,这还不够。你也可以试试看。你能解释一下你试过什么吗?您的SQL语句中存在一些基本缺陷
.我只是想了解如何使用SQL::Abstract或SQL::Abstract::More进行一些复杂的查询。我知道这个声明中有一些缺陷,比如我刚得到的。文档不够好@koriander您是对的,这还不够。您还可以尝试查看代码的结果:sqlite>select*from table1;1 | ahsdf从表1 |中选择maxid+1,这样它就不能正常工作。是的,对不起。我以前没有用DBI在select中尝试过select,但我将anwser更新为一个可能适合您的解决方案,即使它没有那么智能。我想一步创建sql语句。我可以在两步甚至不用SQL::Abstract的情况下做同样的事情,但是如果可能的话,我必须学习如何使用这个模块创建复杂的查询。我的语句的语法是正确的,这是允许的。谢谢你的关注,我理解。然而,旧的anwser是一个正确的SQL语句,它不起作用的原因是,当您执行它时,该值被捕获在两个单引号之间。因此,我编写的代码符合您的要求,生成了正确的语句。您需要查找的是如何将此变量传递给DBI模块并去掉引号,值“从表1中选择maxid+1”必须更改为值从表1中选择maxid+1。我查看了DBI文档,但没有找到anwser。对不起,您代码的结果是:sqlite>select*from table1;1 | ahsdf从表1 |中选择maxid+1,这样它就不能正常工作。是的,对不起。我以前没有用DBI在select中尝试过select,但我将anwser更新为一个可能适合您的解决方案,即使它没有那么智能。我想一步创建sql语句。我可以在两步甚至不用SQL::Abstract的情况下做同样的事情,但是如果可能的话,我必须学习如何使用这个模块创建复杂的查询。我的语句的语法是正确的,这是允许的。谢谢你的关注,我理解。然而,旧的anwser是一个正确的SQL语句,它不起作用的原因是,当您执行它时,该值被捕获在两个单引号之间。因此,我编写的代码符合您的要求,生成了正确的语句。您需要查找的是如何将此变量传递给DBI模块并去掉引号,值“从表1中选择maxid+1”必须更改为值从表1中选择maxid+1。我查看了DBI文档,但没有找到anwser。对不起,我喜欢你的解决方案。谢谢赏金是你的!我喜欢你的解决方案。谢谢赏金是你的!