20

int 型の列がいくつかありますが、値は空です。そのため、データベースに挿入するときに空を null に変換したいと考えています。私はコードを使用します:

function toDB($string) {
    if ($string == '' || $string == "''") {
        return 'null';
    } else {
        return "'$string'";
    }
}

//age,month,year is type integer.
$name="Veo ve";
$age='10';
$month='';
$year='';
    $query="Insert Into tr_view(name,age,month,year) values ({toDB($name)},{toDB($age)},{toDB($month)},{toDB($year)})
 $db->setQuery($query);
 $result= $db->query();

しかし、それはエラーを示しています:

 pg_query(): Query failed: ERROR: syntax error at or near ";" LINE 153: {toDB(10)}, ^ in...

なんで?

4

2 に答える 2

77

機能がありNULLIF()ます:

SELECT NULLIF(var, '');

var$2 の値を保持している場合は、NULL代わりに取得します。
この例では、空の文字列:''をに置き換えNULLます。

integer 型に空の文字列はありません。不可能です。NULLIF()データ型を切り替えることができないため、PHP で入力をサニタイズする必要があります。

列のデフォルトを定義しなかった場合は、コマンドで列を省略することもできます。これはデフォルトの です。INSERTNULLDEFAULT

PHP でパラメータが空かどうかを確認し、空であるINSERT場合はコマンドに列を含めないでください。

または、 Quassnoi がここで示しているように、代わりにPHP リテラル NULLを使用します。

残りは文字列型の場合にのみ意味があります

絶対に確認するために、誰も空の文字列を入力できないようCHECKに、テーブルに制約を追加します。

ALTER TABLE tr_view
ADD CONSTRAINT tr_view_age_not_empty CHECK (age <> '');

これによる例外を回避するために、入力を自動的に修正するトリガーを追加できます。

CREATE OR REPLACE FUNCTION trg_tr_view_avoid_empty()
  RETURNS trigger AS
$func$
BEGIN
   IF NEW.age = '' THEN
      NEW.age := NULL;
   END IF;

   IF NEW.month = '' THEN
      NEW.month := NULL;
   END IF;

   RETURN NEW;
END
$func$  LANGUAGE plpgsql

CREATE TRIGGER tr_view_avoid_empty
BEFORE INSERT OR UPDATE ON tr_view
FOR EACH ROW
WHEN (NEW.age = '' OR NEW.month = '')
EXECUTE PROCEDURE trg_tr_view_avoid_empty();
于 2012-12-26T04:05:33.753 に答える
8

アーウィンの答えNULLIF素晴らしいですが、構文エラーには対処していません。

クエリを見てみましょう。

$query="Insert Into tr_view(name,age,month,year) values ({toDB($name)},{toDB($age)},{toDB($month)},{toDB($year)})

前に、 という関数を定義しましたtoDB。残念ながら、ここで使用している構文は、二重引用符で囲まれた文字列内から関数を呼び出す方法ではないtoDB(ため、カーリーとビットは引き続き渡されます。次の 2 つの方法があります。

  1. を使用した連結.:

    $query='insert Into tr_view(name,age,month,year) values (' . toDB($name) . ',' . toDB($age) . ',' . toDB($month) . ',' . toDB($year) . ')')
    
  2. 次のように、呼び出し可能な変数を二重引用符で囲まれた文字列に補間できます。

    $fn = 'toDB';
    $query="Insert Into tr_view(name,age,month,year) values ({$fn($name)},{$fn($age)},{$fn($month)},{$fn($year)})";
    

1 つ目は明確で正気ですが、2 つ目は不慣れで正気でない人にとっては漠然としたものです。

ただし、このように入力を組み立てるべきではありません。それでも、 SQL インジェクション攻撃に対して脆弱である可能性があります。パラメーター化されたプレースホルダーで準備済みステートメントを使用する必要があります。

Postgres 拡張機能はこれを使用pg_prepareします。nullこれらには、null 検出と引用のすべてを心配する代わりに、PHP を渡すことができるという明確な利点があります。

そのままにしておくことを主張する場合は、引用符で囲まれた文字列を構築するものに、 のような関数toDBの 1 つを追加することを検討してください。pg_escape_pg_escape_string

于 2012-12-26T05:22:25.507 に答える