![](/img/trans.png)
[英]Perl, SQL, DBI: Why doesn't my UPDATE function work? Code and things I've tried inside
[英]Perl, DBI, and SQL: Why NOT does not work in some SQL queries?
我有一個最奇怪的問題,我對SQL的非常基本的知識必定是非常錯誤的,但我無法理解下面說明的行為。
我有這個文件test.csv
id,field
A,0
B,1
C,2
D,"0"
E,"1"
F,"2"
G,
H,""
I," "
而這個測試代碼:
#! /usr/bin/perl
use strict;
use warnings;
use DBI;
use Devel::VersionDump qw(dump_versions);
my $dbh = DBI->connect ("dbi:CSV:");
$dbh->{RaiseError} = 1;
$dbh->{TraceLevel} = 0;
my $i = 0;
foreach my $cond ("TRUE",
"field <> 0 AND field <> 1",
"field = 0 OR field = 1",
"NOT (field = 0 OR field = 1)",
"NOT field = 0 OR field = 1",
"field <> 0",
"NOT field <> 0",
) {
print "Condition #" . $i++ . " is $cond:\n";
my $sth = $dbh->prepare("SELECT * FROM test.csv WHERE $cond");
$sth->execute();
$sth->dump_results();
};
print "\n\n";
dump_versions();
運行時,這是輸出:
Condition #0 is TRUE:
'A', '0'
'B', '1'
'C', '2'
'D', '0'
'E', '1'
'F', '2'
'G', ''
'H', ''
'I', ' '
9 rows
Condition #1 is field <> 0 AND field <> 1:
'C', '2'
'F', '2'
'G', ''
'H', ''
'I', ' '
5 rows
Condition #2 is field = 0 OR field = 1:
'A', '0'
'B', '1'
'D', '0'
'E', '1'
4 rows
Condition #3 is NOT (field = 0 OR field = 1):
'A', '0'
'B', '1'
'D', '0'
'E', '1'
4 rows
Condition #4 is NOT field = 0 OR field = 1:
'B', '1'
'C', '2'
'E', '1'
'F', '2'
'G', ''
'H', ''
'I', ' '
7 rows
Condition #5 is field <> 0:
'B', '1'
'C', '2'
'E', '1'
'F', '2'
'G', ''
'H', ''
'I', ' '
7 rows
Condition #6 is NOT field <> 0:
'A', '0'
'D', '0'
2 rows
Perl version: v5.16.3 on MSWin32 (C:\Program Files\Perl64\bin\perl.exe)
ActivePerl::Config - Unknown
ActiveState::Path - 1.01
AutoLoader - 5.73
C:::Program Files::Perl64::site::lib::sitecustomize.pl - Unknown
Carp - 1.26
Class::Struct - 0.63
Clone - 0.34
Config - Unknown
Config_git.pl - Unknown
Config_heavy.pl - Unknown
Cwd - 3.40
DBD::CSV - 0.41
DBD::File - 0.42
DBI - 1.631
DBI::DBD::SqlEngine - 0.06
DBI::SQL::Nano - 1.015544
Data::Dumper - 2.139
Devel::VersionDump - 0.02
DynaLoader - 1.14
Encode - 2.49
Encode::Alias - 2.16
Encode::Config - 2.05
Encode::Encoding - 2.05
Errno - 1.15
Exporter - 5.67
Exporter::Heavy - 5.67
Fcntl - 1.11
File::Basename - 2.84
File::Spec - 3.40
File::Spec::Unix - 3.40
File::Spec::Win32 - 3.40
File::stat - 1.05
IO - 1.25_06
IO::Dir - 1.1
IO::File - 1.16
IO::Handle - 1.33
IO::Seekable - 1.1
List::Util - 1.27
Math::BigFloat - 1.997
Math::BigInt - 1.998
Math::BigInt::Calc - 1.997
Math::Complex - 1.59
Math::Trig - 1.23
Params::Util - 1.07
SQL::Dialects::AnyData - 1.405
SQL::Dialects::Role - 1.405
SQL::Eval - 1.405
SQL::Parser - 1.405
SQL::Statement - 1.405
SQL::Statement::Function - 1.405
SQL::Statement::Functions - 1.405
SQL::Statement::Operation - 1.405
SQL::Statement::Placeholder - 1.405
SQL::Statement::RAM - 1.405
SQL::Statement::Term - 1.405
SQL::Statement::TermFactory - 1.405
SQL::Statement::Util - 1.405
Scalar::Util - 1.27
SelectSaver - 1.02
Symbol - 1.07
Text::CSV_XS - 1.07
Tie::Hash - 1.04
Time::HiRes - 1.9725
Win32 - 0.47
XSLoader - 0.16
base - 2.18
bytes - 1.04
constant - 1.25
integer - 1.00
overload - 1.18
overloading - 0.02
sort - 2.01
strict - 1.07
unicore::Heavy.pl - Unknown
unicore::lib::Perl::Word.pl - Unknown
unicore::lib::Perl::_PerlIDS.pl - Unknown
utf8 - 1.09
utf8_heavy.pl - Unknown
vars - 1.02
warnings - 1.13
warnings::register - 1.02
條件#0顯示完整的數據集,並且沒問題。
條件#1只是一些復合條件,工作正常。
條件#2是相反的條件(用於反轉它的基本邏輯規則),並且也可以正常工作。
然而,條件#3應該與#2相反,因此等於#1,但結果與#2相同: 我無法理解這一點 。
條件#4表明,省略括號,NOT確實可以正常工作,但當然這個查詢與以前的查詢不同。
條件#5和#6顯示出一種情況,其中NOT的行為與預期的完全一致。
那么,為什么不在復合條件下表現得好像根本沒有指定NOT?!
順便說一句,我讀了這篇可怕的帖子Perl DBD :: CSV - SQL語法 - “AND”子句無法正常工作並添加了Devel :: VersionDump來檢查我是否有類似的問題,但在我看來,所有相關的包都是最新的。 因此,我真的不知道這個。
我確認這是SQL :: Parser的一個錯誤:
'where_clause' => HASH(0x7f9686737480)
'arg1' => HASH(0x7f9686808248)
'arg1' => HASH(0x7f96866b50f8)
'fullorg' => 'field'
'type' => 'column'
'value' => 'field'
'arg2' => HASH(0x7f968588dfe0)
'fullorg' => 0
'type' => 'number'
'value' => 0
'neg' => 0
'nots' => HASH(0x7f96866b55d8)
empty hash
'op' => '='
'arg2' => HASH(0x7f9684498ce0)
'arg1' => HASH(0x7f96845fb798)
'fullorg' => 'field'
'type' => 'column'
'value' => 'field'
'arg2' => HASH(0x7f96866b5158)
'fullorg' => 1
'type' => 'number'
'value' => 1
'neg' => 0
'nots' => HASH(0x7f96866b55a8)
empty hash
'op' => '='
'neg' => 0
'nots' => HASH(0x7f9686808320)
empty hash
'op' => 'OR'
最頂層的“neg”應該是1.請在https://rt.cpan.org/Dist/Display.html?Name=SQL-Statement上打開一張票 - 當你引用這個帖子時,測試用例已被證實: )
干杯,詹斯
DBD :: CSV的SQL邏輯不包含在DBD :: CSV中,它只是Text :: CSV_XS和DBI之間的一個薄粘合層。
所有SQL知識都由SQL :: Statement處理。 如果你認為你發現了一個真正的錯誤,請嘗試挖掘該模塊並查找原因,創建補丁並在RT上發布補丁問題:)
如果這確實恰好是NOT
在括號上的分布錯誤,你可以通過替換來快速修復它
NOT (A OR B)
同
NOT A AND NOT B
這在邏輯意義上相當於前者。 這可能沒有回答為什么你的代碼失敗的問題,但是如果這有效,而另一個沒有,那么我認為這是一個錯誤(或者可能是分配不實現,不知道廣告應該是什么工作什么不是。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.