0

私のwebAppは2つのデータベースサーバーInformixとDB2(v9.5はlocalhostで実行)で動作します。informixDBで動作する場合、主キーにnullを挿入できます(informix DBはそれを処理し、nullを受け入れ、列を自動インクリメントします(Serial8))しかし、DB2を使用するように切り替えた場合、それは機能せず、このエラーが発生します(DB2 SQLエラー:SQLCODE = -407、SQLSTATE = 23502、SQLERRMC = TBSPACEID = 2、TABLEID = 280、COLNO = 0、DRIVER = 3.50.152、 sqlCode = -407)DB2は主キー(BigInt)にnullを許可していないようですが、DB2を強制して主キーにnullを許可するにはどうすればよいですか?つまり、DB2でこの列にヌルを挿入し、挿入するたびにその列の値を自動インクリメントできるようにしたいのです。

テーブルを作成するためのスクリプトは次のとおりです。

CREATE TABLE corr.CORRESPONDENCE  (
this is the specified col---->CORR_ID BIGINT NOT NULL,
    CORR_NAME VARCHAR(255) NOT NULL,
    CORR_NO VARCHAR(255),
    CREATE_DATE_TIME TIMESTAMP NOT NULL,
    DELIVERY_DATE_TIME DATE,
    NO_OF_ATTACH INTEGER,
    SITE_ID VARCHAR(20),
    DELIVERY_ID VARCHAR(20),
    CREATE_USER BIGINT NOT NULL,
    SECURITY_ID BIGINT,
    DELIVERY_BY VARCHAR(20),
    WORKFLOW_ID BIGINT
)
DATA CAPTURE NONE ;

ALTER TABLE corr.correspondence ADD CONSTRAINT u143_159 PRIMARY KEY 
(corr_id)  ;
4

4 に答える 4

2

Which version of Informix? What is the schema of the table? What is the INSERT statement? Which API are you using to access Informix? Which platform is the client code running on? Which platform is the database server running on?

I'm not convinced that you can insert nulls into a SERIAL-like column in Informix. Do you have a primary key constraint on your table, or just a SERIAL8 column that has no NOT NULL and no PRIMARY KEY constraint on it? You cannot insert NULL directly into a SERIAL8 column (nor, by inference, into a SERIAL or BIGSERIAL column).

Demonstration (using a development version of Informix 11.70.FC6 on RHEL 5 Linux x86/64; client is ESQL/C based, and both client and server are on the same machine):

SQL[1910]: begin;
SQL[1911]: create table t1(s8 serial8 not null, v1 char(8) not null);
SQL[1912]: insert into t1(s8, v1) values(null, "works?");
SQL -391: Cannot insert a null into column (t1.s8).
SQLSTATE: 23000 at /dev/stdin:6
SQL[1913]: rollback;
SQL[1914]: begin;
SQL[1915]: create table t1(s8 serial8 primary key, v1 char(8) not null);
SQL[1916]: insert into t1(s8, v1) values(null, "works?");
SQL -703: Primary key on table (t1) has a field with a null key value.
SQLSTATE: IX000 at <<temp>>:2
SQL[1917]: rollback;
SQL[1918]: create table t1(s8 serial8, v1 char(8) not null);
SQL[1919]: insert into t1(s8, v1) values(null, "works?");
SQL -391: Cannot insert a null into column (t1.s8).
SQLSTATE: 23000 at <<temp>>:2
SQL[1920]: drop table t1;
SQL[1921]:

And bother, I forgot to restart the transaction after 1917!

This is behaving exactly as it should; you should not be allowed to insert a NULL into a SERIAL8 (or SERIAL, or BIGSERIAL) column. You can insert zeroes into those columns and a new value will be allocated automatically. But you cannot, and should not be able to, insert a NULL into the column.

DB2 is likewise correct in rejecting attempts to insert NULL into any of the columns in a primary key. It simply is not something you should be allowed to do.


Answering comments

Frank Computer commented:

Strange, I was under the impression that when loading data into a table with a SERIAL column, if I did not supply a value for the SERIAL column, it would convert the NULL to a zero during the insert, as if the loaded data contained a zero?

Also, with ISQL Perform, when I insert a new row into a table containing a SERIAL column, I don't supply a value for the SERIAL column, yet Perform displays a zero (0) and after hitting Escape, it converts it to the next highest INT value!

My immediate response was:

  • LOAD is done by a complex sub-routine in the client that munges the data, and it could/would deal with NULL for SERIAL columns.

  • With ISQL, Perform explicitly enforces 0 during data entry and reports back on the inserted value; again, the client-side code is preventing the error.

This is why it is important to know what is in use to demonstrate problems or features. Now I've got to make a LOAD and NULL demo using DB-Access...I don't think my SQLCMD program fixes up NULL for SERIAL columns during LOAD (or, if it does, I made that hack a long, long time ago).

Testing DB-Access (from IDS 11.70.FC2 on Mac OS X 10.7.4, this time), with:

xx.unl

|data for row 1|1|
|data for row 2|2|

xx.sql

BEGIN;
CREATE TABLE load_null(s8 SERIAL8 PRIMARY KEY, v32 VARCHAR(32) NOT NULL, i INTEGER NOT NULL);
LOAD FROM "xx.unl" INSERT INTO load_null;
ROLLBACK;

DB-Access Output

$ dbaccess stores xx

Database selected.


Started transaction.


Table created.


  703: Primary key on table (load_null) has a field with a null key value.

  847: Error in load file line 1.
Error in line 3
Near character position 41

Transaction rolled back.


Database closed.

$

This does not lend support to the 'DB-Access maps NULL for a SERIAL8 column into a zero' hypothesis. This is SERIAL8 rather than plain SERIAL, but when I changed SERIAL8 into SERIAL, I got the same error; ditto with BIGSERIAL. I don't have ISQL as opposed to DB-Access on the Mac (laziness; I did the port a while ago, but didn't install it as it was not official, and it is not GA), and it is possible that there's a difference between the two LOAD commands, but relatively unlikely.

Testing SQLCMD on the same SQL and data (unload) files, I get the same error message.

I am more than ever unconvinced by the claim that it is possible to insert NULL values into a primary key column with Informix.


More comments and explanations

Although I know LOAD is not an Informix SQL native statement, I assumed it was added to the SE (Standard Engine) and OL (OnLine) engines?

No; the LOAD statement is handled by code in client programs: DB-Access, ISQL, I4GL, DB-Load, DB-Import. In each case, the statement is recognized and parsed by the client, converted into a suitable INSERT statement that is prepared, then the client reads and parses the data file, and sends the data to the server one row at a time (logically; actually, there's an INSERT cursor involved which gives you batch operation on insertions).

Or does LOAD statement actually call the DBLOAD.EXE utility in SE/OL or onload.exe?

No: the LOAD statement does not involve DB-Load, nor does it involve ON-Load.

Is the source for SQLCMD available? If so, can I dump dbaccess and replace it with a stripped down version of SQLCMD?

Yes. It is available from the IIUG (International Informix User Group) Software Archive. The version available there (87.02) is close to current (I'm using 87.06, but I'm not quite ready to release that to the rest of the world, and it'll be 88.00 when it is released). I don't support it on Windows, simply because I find Windows too hostile a development environment. It has, on occasion, been made to work on Windows, though. My last attempt stopped when I found Microsoft promulgating the 'Safe C Library' routines, but the routines they provide are not the same as the ones in the standard TR 27341. I gave up again at that point.

I just confirmed that my ole SE-4.10 clunker accepts NULL values for SERIAL columns when inserting a load file with LOAD.

OK. You couldn't specify PRIMARY KEY constraints in that version (those arrived with 5.00, I'm almost certain), but you could create unique indexes on SERIAL columns, etc. To the extent that it is a bug, it has presumably been fixed. It might or might not be fixed in SE 7.26; I'd expect it to be, but haven't demonstrated that it is. It is fixed in 11.70; my tests above demonstrate that.

于 2012-07-11T22:36:33.357 に答える
1

問題を解決するには、次の SQL ステートメントを試してください。

insert into table(primarykey,c1, ...) values(null,v1,...).
Try insert into table(c1,...) values(v1,...)
于 2012-07-11T17:17:37.033 に答える
1

主キー DB2 に null 値を挿入することはできません。代わりに、挿入クエリを変更して新しいキーを挿入するか、Insert ステートメントに含めずにデータベースに自動的に処理させる必要があります...

挿入クエリ (または少なくともその一部) を知っていると役立ちます。それを修正する方法について、より良いガイダンスを提供できます。ただし、問題の原因を推測してください。

テーブルが次のようになっていると仮定します。

ID INTEGER NOT NULL GENERATED DEFAULT (START WITH 1, INCREMENT BY 1)
SomeOtherField VARCHAR(50)

あなたの声明は次のとおりです。

Insert into MyTable (SomeOtherField) Values ('somevalue')

それ以外の

Insert into MyTable (ID, SomeOtherField) Values (null, 'somevalue')

また

Insert into  Values (null, 'somevalue')

同様の質問と詳細情報は、http ://www.dbforums.com/db2/669352-autoincrement-fields.html にあります。

于 2012-07-11T17:17:04.320 に答える
1

Informix SERIAL 列を使用すると、ゼロ (0) を挿入できます。ゼロ (0) は、使用可能な次に大きい整数値に自動的に変換されます。SERIAL 列には一意の制約があるため、まだ使用されていない限り、特定の整数値を挿入することもできます。

あなたの質問はあいまいです。主キーは非 SERIAL データ型にすることもでき、NULL 値を受け入れることができます。この場合、各行を一意に識別するために代理キー (通常は自動インクリメント列) を作成することをお勧めします。

主キーは何のために使用され、主キーに NULL を挿入する理由は何ですか?値?.. 主キーとして NULL を使用すると、特に子テーブルの外部キーに結合する場合に、正しく動作しない傾向があります。主キーに一意の制約がない場合、それは主キーとして重複する NULL 値を持つ複数の行を持つことができることを意味します..DB2 を含むどの DB でも良い考えではありません!

于 2012-07-11T22:01:47.877 に答える