当前位置: 首页 > 知识库问答 >
问题:

如何使用SQLite使DBIx::Class按顺序忽略大小写?

彭朝
2023-03-14

通常SQLite的排序规则区分大小写。所有大写字母都在小写字母之前。但是可以在ORDER BY子句中告诉SQLite忽略这一点,方法是:

... ORDER BY foo COLLATE NOCASE ASC

但是我们如何使用DBIx::Class来实现这一点呢?

考虑下面的示例,它将一个SQLite数据库部署到内存中,表中包含“代码> Foo”和“一个目录<代码>栏<代码>。连接使用quote_name设置。它填充值zzbbaa,然后使用结果集上的all将它们取出来。我将在以下所有示例中使用此设置。您需要DBIx::Class和DBD::SQLite来运行它。

use strict;
use warnings;

package Foo::Schema::Result::Foo;
use base 'DBIx::Class::Core';
__PACKAGE__->table("foo");
__PACKAGE__->add_columns( "bar", { data_type => "text" }, );

package Foo::Schema;
use base 'DBIx::Class::Schema';

__PACKAGE__->register_class( 'Foo' => 'Foo::Schema::Result::Foo' );

package main;
my $schema = Foo::Schema->connect(
    {
        dsn         => 'dbi:SQLite:dbname=:memory:',
        quote_names => 1,
    }
);
$schema->deploy;

$schema->resultset('Foo')->create( { bar => $_ } ) for qw(z Z b B a A);
my @all = $schema->resultset('Foo')->search(
    {},
    {
        order_by => { -asc => 'me.bar' },
    },
)->all;

# example code starts here

print join q{ }, map { $_->bar } @all;

此文件的输出区分大小写。

A B Z a b z

现在我当然可以用Perl对它进行排序,并使它不区分大小写,就像这样。

print join q{ }, sort { lc $a cmp lc $b } map { $_->bar } @all;

现在我明白了

A a B b Z z

但如果直接使用底层DBI句柄进行查询,我也可以使用COLLATE NOCASE

$schema->storage->dbh_do(
    sub {
        my ( $storage, $dbh, @args ) = @_;
        my $res = $dbh->selectall_arrayref(
            "SELECT * FROM foo ORDER BY bar COLLATE NOCASE ASC"
        );
        print "$_->[0] " for @$res;
    }

这给了我们

a A b B z Z  

我希望DBIC使用COLLATE NOCASE,但不运行任何SQL。我不想在ORDER BY中进行任何昂贵的字符串转换,或者以后在Perl中进行转换。

在使用SQLite订购时,我如何告诉DBIx::Class使用COLLATE NOCASE

以下情况不起作用:

order_by => { '-collate nocase asc' => 'me.bar' },

只有当quote_names未打开时,这才有效。

order_by => { -asc => 'me.bar COLLATE NOCASE' },

它将使用上述示例代码生成此查询和错误消息

选择me. bar from"foo"me"ORDER BY"me". bar COLLATE NOCASE"ASC: DBIx::Class::Storage::DB::_prepare_sth(): DBI异常:DBD::SQLite::db prepare_cached失败:没有这样的列:me.barCOLLATE NOCASE[for语句"SELECT"me"."bar"from"foo"me"ORDER BY"me"."bar COLLATE NOCASE"ASC"]

或者我可以通过使用DBIC将ORDER by子句中的upperlower转换为

my @all = $schema->resultset('Foo')->search(
    {},
    {
        order_by => { -asc => 'lower(me.bar)' },
    },
)->all;

print join q{ }, map { $_->bar } @all;

这给

a A b B z Z

没有quote_names,这是相似的,但相反。(这不是我关心的问题),但在启用quote_names时也会抛出一个错误。

选择“我”。从“foo”到“me”的顺序是“lower(me”。“bar)”ASC:DBIx::Class::Storage::DBI::_prepare_sth():DBI异常:DBD::SQLite::db prepare_cached失败:没有这样的列:lower(me.bar)[对于语句“SELECT”me.]从“foo”到“me”,用“lower(me)”来表示“bar”bar)“ASC”]

共有1个答案

太叔高义
2023-03-14

如果您对使用非常少量的SQL感到满意,那么可以传递一个标量引用来表示文字SQL,DBIC不会弄乱它:

order_by => \'me.bar COLLATE NOCASE ASC'

或者,只有最少的文字SQL:

order_by => { -asc => \'me.bar COLLATE NOCASE' }

请注意,这种语法在技术上是不鼓励的,但是我不知道还有什么其他方法可以实现你想要的:

旧的scalarref语法(即order_by=

 类似资料:
  • 问题内容: 我想使用方法但忽略大小写。 假设我有“会话”,并且在“ sEsSi”上使用了它,那么它应该返回。 我该如何实现? 问题答案: 在测试之前,请使用或标准化您的字符串。

  • (我用的是Micronaut)我有一个学生名单,我想按名字排序。我正在使用Pageable和sort作为查询参数 萨曼莎 蒂姆 安东尼奥 大卫 索菲亚 而不是: 安东尼奥 大卫 萨曼莎 索菲亚 蒂姆 会有什么问题?

  • 我是DBIx::Class的新手。我用它作为API从我的数据库中重新运行数据,我想用DBIC重新创建一个SELECT*from表。对于DBI,它对我很有效 返回数据“漂亮”的最佳方法是什么 我想以哈希数组的形式返回数据,如: 但是使用

  • 我正在使用一个regex来验证angular2应用程序中的一些内容: 我只想允许数字(0-9)和字母F,N,K,J,K和J应该是可选的,F和N必须正好在里面一次。 有人知道吗,如何忽略字母和数字的顺序?不,它只是匹配,如果我完全按照以下顺序插入字符:012FNKJ。KJFN012根本不匹配。:(

  • DBIx::Class 是一个Perl语言的数据库对象映射框架

  • 问题内容: 这是我的代码: 对于用户如何输入命令,我希望允许他们留有余地,例如:右上,右上,TOPRIGHT,左上等。为此,我试图在最后一点,检查是否以“ top”或“ up”开头,并检查是否以“ left”或“ right”结尾,并且不区分大小写。这是可能吗? 这样做的最终目的是允许用户在输入的一行中从三角形的四个方向之一中进行拾取。这是我想到的最好方法,但是对于一般的编程我还是很陌生,可能会使