sql >> データベース >  >> RDS >> SQLite

SQLiteにデータを挿入するときに、NULL値を列のデフォルト値に変換する

    SQLiteのSQLに対する非標準の拡張機能の1つは、ON CONFLICTです。 条項。

    この句を使用すると、制約違反が原因で特定の競合が発生した場合に何が発生するかを判断できます。

    この句を使用できることの1つは、NULLを置き換えることです。 テーブルにデータを挿入または更新するときの列のデフォルト値を持つ値。

    デフォルトでは、NULLを明示的に挿入しようとすると NOT NULLの列に 制約、それは失敗します。

    また、NULLを明示的に挿入しようとすると なしの列に NOT NULL 制約、次にNULL DEFAULTがある場合でも、その列に割り当てられます 条項。

    ただし、ON CONFLICTは使用できます NULLではなくデフォルト値に設定する句 。

    次のコードは、私が何を意味するかを示しています。

    DROP TABLE IF EXISTS Products;
    
    CREATE TABLE Products( 
        ProductId INTEGER PRIMARY KEY, 
        ProductName NOT NULL, 
        Price NOT NULL ON CONFLICT REPLACE DEFAULT 0.00
    );
    
    INSERT INTO Products (ProductId, ProductName, Price) VALUES 
        (1, 'Widget Holder', NULL);
    
    SELECT * FROM Products;

    この例では、ON CONFLICT REPLACEを使用します NULLを設定するには 値をNULLではなくデフォルト値に変更 。

    これがSELECTの結果です 最後の行のステートメント:

    ProductId   ProductName    Price     
    ----------  -------------  ----------
    1           Widget Holder  0.0       

    価格がわかります NULLを明示的に挿入しようとしましたが、columnのデフォルト値は0.0です。 。

    NOT NULLを削除するとどうなるか見てみましょう 制約。

    DROP TABLE IF EXISTS Products;
    
    CREATE TABLE Products( 
        ProductId INTEGER PRIMARY KEY, 
        ProductName NOT NULL, 
        Price DEFAULT 0.00
    );
    
    INSERT INTO Products (ProductId, ProductName, Price) VALUES 
        (1, 'Widget Holder', NULL);
    
    SELECT * FROM Products;

    結果:

    ProductId   ProductName    Price     
    ----------  -------------  ----------
    1           Widget Holder            

    これで、列にNULLが含まれます 。

    暗黙的にNULLを挿入する

    この記事は主にNULLの挿入に関係していることに注意してください。 明示的に

    NULLを挿入しようとした場合 暗黙的に 、その場合、前の例では異なる結果が生成されます。

    つまり、INSERTに列を含めない場合です。 ステートメント、DEFAULT 制約は自動的に使用されます。それがDEFAULT 制約は–明示的に値を提供しない場合に値を提供するためのものです。

    これを行うとどうなりますか。

    DROP TABLE IF EXISTS Products;
    
    CREATE TABLE Products( 
        ProductId INTEGER PRIMARY KEY, 
        ProductName NOT NULL, 
        Price DEFAULT 0.00
    );
    
    INSERT INTO Products (ProductId, ProductName) VALUES 
        (1, 'Widget Holder');
    
    SELECT * FROM Products;

    結果:

    ProductId   ProductName    Price     
    ----------  -------------  ----------
    1           Widget Holder  0.0       

    だから私がしたのは価格を削除することだけでした INSERTの列 ステートメント。

    INSERTステートメントの競合について

    最初の例では、ON CONFLICTを使用しています CREATE TABLEで ステートメント。

    ただし、テーブルがON CONFLICTで作成されていない場合はどうなりますか 条項?

    幸い、INSERTで使用する方法もあります 声明。

    構文は少し異なります。 INSERTで使用する場合 ON CONFLICTを置き換える必要があるステートメント ORを使用 。

    このメソッドを使用するようにコードを変更しましょう。

    DROP TABLE IF EXISTS Products;
    
    CREATE TABLE Products( 
        ProductId INTEGER PRIMARY KEY, 
        ProductName NOT NULL, 
        Price NOT NULL DEFAULT 0.00
    );
    
    INSERT OR REPLACE INTO Products (ProductId, ProductName, Price) VALUES 
        (1, 'Widget Holder', NULL);
    
    SELECT * FROM Products;

    結果:

    ProductId   ProductName    Price     
    ----------  -------------  ----------
    1           Widget Holder  0.0       

    そこで、INSERT INTOを置き換えました INSERT OR REPLACE INTOを使用 。

    その条項を入れなかった場合の結果は次のとおりです。

    DROP TABLE IF EXISTS Products;
    
    CREATE TABLE Products( 
        ProductId INTEGER PRIMARY KEY, 
        ProductName NOT NULL, 
        Price NOT NULL DEFAULT 0.00
    );
    
    INSERT INTO Products (ProductId, ProductName, Price) VALUES 
        (1, 'Widget Holder', NULL);
    
    SELECT * FROM Products;

    結果:

    Error: NOT NULL constraint failed: Products.Price

    デフォルトの制約はありませんか?

    ON CONFLICTを使用する場合 DEFAULTのない列の句 制約がある場合、SQLステートメントはSQLITE_CONSTRAINTエラーで中止され、現在のSQLステートメントによって行われた変更はすべて取り消されます。ただし、同じトランザクション内の以前のSQLステートメントによって引き起こされた変更は保持され、トランザクションはアクティブなままです。


    1. テーブルから重複を削除します

    2. MySQLを再起動せずにMySQLの遅いクエリログを有効にするにはどうすればよいですか?

    3. SQLAlchemyキャッシングを無効にする方法は?

    4. SQL Serverテーブルに2つのID列を含めることはできますか?