3

前提

select最近、コード内のステートメントでバグに遭遇しました。何が起こっているのかを理解した後、修正するのはかなり簡単でしたが、同様のバグが再び発生しないようにする方法を見つけることに興味があります.

問題のあるクエリの例を次に示します。

select
  the,
  quick,
  brown
  fox,
  jumped,
  over,
  the,
  lazy,
  dog
from table_name;

私が意図していたのは:

select
  the,
  quick,
  brown,
  fox,
  jumped,
  over,
  the,
  lazy,
  dog
from table_name;

brown前者は後ろのカンマが抜けています。これにより、asキーワードが不要なため、列がエイリアス化されます。したがって、結果は次のようになります。

  the,
  quick,
  fox,
  jumped,
  over,
  the,
  lazy,
  dog

...brownという名前の列にのすべての値がありますfox。これは、上記のような短いクエリ (特に各列の値が非常に異なる場合) の場合は非常に簡単に気付くことができますが、次のようなほとんどが整数列のかなり複雑なクエリで発生しました。

select
  foo,
  bar,
  baz,
  another_table.quux,
  a1,
  a2,
  a3,
  a4,
  a5,
  a6,
  a7,
  a8,
  a9,
  a10,
  a11,
  a12,
  a13,
  a14,
  a15,
  a16,
  b1,
  b2,
  b3,
  b7,
  b8,
  b9,
  b10,
  b11,
  b12,
  b13,
  b14,
  b18,
  b19,
  b20,
  b21,
  c1,
  c2,
  c3,
  c4,
  c5,
  c6,
  c7,
  c8
from table_name
join another_table on table_name.foo_id = another_table.id
where
  blah = 'blargh'
-- many other things here
;

より良い列名を使用しても、値はすべて非常に似ています。b11(たとえば) の後にカンマを逃して、すべてのb11値が呼び出されb12た場合、処理パイプラインを介してデータを実行するときに非常に残念です (結果の列名によって異なります)。通常ならそうしますselect * from table_nameが、それよりももう少し厳選する必要がありました。

質問

私が探しているのは、これが再び起こらないようにするための戦略です。

as列をエイリアシングするときに要求する方法はありますか? または、エラーを発生させるための書き方のトリックですか?(たとえば、C ライクな言語では、誤って等号を忘れてコンパイル エラーが発生するのではなく、代わりに無効にして、1 == foo書き始めました。)foo == 11 = foofoo = 1

私はvim通常使用しているので、目で見ることができるhlsearchようにコンマを強調表示するために使用できます。ただし、このようなことを簡単に行うことができない独自のインターフェイスを含め、他の環境でクエリを頻繁に作成する必要があります。

ご協力いただきありがとうございます!

4

5 に答える 5

6

以前に行ったことの 1 つは、コンマを行頭に移動することです。これにより、いくつかの利点が得られます。まず、コンマがないかどうかをすぐに確認できます。次に、以前の最後の行を変更することなく、最後に新しい列を追加できます。

ない:

select
  the
, quick
, brown
  fox
, jumped
, over
, the
, lazy
, dog
from table_name;

欠落していません:

select
  the
, quick
, brown
, fox
, jumped
, over
, the
, lazy
, dog
from table_name;
于 2009-11-19T16:51:56.797 に答える
1

私はあなたと同じ問題を抱えています。私は長い間、makeとperlスクリプトを使用して、コードをチェックするような「lint」を実行してきました。これは、このような多くの間違いを防ぐのに役立ちました。makefileには次のものがあります。

lint_code:
    perl lint_code.pl <file_1.php

perlファイルは次のとおりです。

$st = 0;
$line_no = 0;
while (<>)
{
   $line_no++;
   $st = 1 if ( /start-sql/ );
   $st = 0 if ( /end-sql/ );
   $st = 2 if ( $st == 1 && /select/ );
   $st = 3 if ( $st == 2 && /from/ );
   if ( $st == 2 && /^[ \t]+[a-zA-Z][a-zA-Z0-9]*[ \t*]$/ )
   {
      if ( ! /select/ )
      {
         printf ( "Possible Error: Line: $line_no\n" );
      }
   }
}

selectステートメントをコメント//start-sqlおよび//end-sqlで囲みます。これがお役に立てば幸いです。別の形式(前にコンマを使用)を使用していたため、SQLの形式を反映するように正規表現を変更しました。

ビルド/テストプロセスの一環として、コードに対して一連のチェックを実行します。これは完璧とは言えない解決策ですが、私を助けてくれました。

(stackoverflowリッチテキストエディターでコードを変更するのに少し問題があります。正しく使用する方法を学ぶことができれば幸いです。)

于 2009-11-19T17:03:26.323 に答える
1

次のいずれかの関数でSQL呼び出しをラップできます。

  1. 結果セットの列を反復処理し、スペースを含む列名を確認します

また

  1. SQLステートメントと整数の意図した列数の両方を受け入れ、結果セットをチェックして、列の数が意図したものと一致することを確認します。
于 2009-11-19T16:53:53.220 に答える
0

名前の前にカンマを書く

first
,short
,medium
,longlonglong
,...

first,
short,
medium,
longlonglong,
...

また、SQL選択引数のリストを簡単に確認できます

どのIDEでも動作します:)

于 2009-11-19T16:50:14.507 に答える
-1

似たような名前の列があり、サフィックス番号だけで区別されている場合は、すでに失われています。データベースの設計が不適切です。

そして最近のほとんどの開発者は、この「アセンブリ言語」SQL を記述する代わりに、SQL ジェネレーターまたは ORM を使用しています。

于 2009-11-19T16:51:09.543 に答える