3

次のエラー メッセージが表示されます。

[FireDAC][Phys][MySQL] キー「PRIMARY」の重複エントリ「1111」

データベースにデータを挿入しようとしたとき。データベース内の唯一のデータは、主キーが「0000」のタプルであるため、主キーが別のキーの複製ではないことがわかっています。データはデータベースに正しく挿入されているので、主キーが重複していないときにエラーが表示されないようにする方法はありますか?

Delphi XE7、MySQL 6.2、FDConnectionおよびFDQuery. 私のコードは次のとおりです。

FDQuery1.SQL.Clear;
FDQuery1.SQL.Add(
  'Insert into Customer (' +
    'CustID,' +
    'Forename,' +
    'Surname,' +
    'Address,' +
    'PostCode' +
  ') ' +
  'Values (' +
    QuotedStr(CustID) + ',' + 
    QuotedStr(Forename) + ',' +
    QuotedStr(Surname) + ',' +
    QuotedStr(Address) + ',' +
    QuotedStr(Postcode) +
  ')'
);
FDQuery1.ExecSQL;
FDQuery1.Open;
4

1 に答える 1

3

同じ SQL ステートメントを 2 回実行しています。最初に でExecSQL、次に でOpen。SQL ステートメントが実際に結果を返すかどうかに応じて、どちらか一方のみを使用する必要があります。

あなたの場合、単純なINSERTクエリを作成したのでExecSQL、正しい選択です。Openこのクエリを ( なしでExecSQL) 使用すると、「開くデータがない」(いわば) ため、エラーが発生することに注意してください。

ルールを強調するには: SQL ステートメントがデータを返す場合に使用Openします。Openこれは、ステートメントが行を挿入する場合でも行う例です。

LQuery.SQL.Text :=
    'INSERT INTO Customer (CustId, CustomerName)'#13#10 +
    'VALUES ('+QuotedStr(ACustId)+','#13#10 +
               QuotedStr(ACustomerName)+');'#13#10 +
    'SELECT  CustId, CustomerName, DateAdded'#13#10 +
    'WHERE   CustId = '+QuotedStr(ACustId)
LQuery.Open;

図に示すように、データベースが値 (デフォルト値、自動キー、rowversion など) を割り当てた場合、挿入直後に新しい行を返すことができます。その場合は、を使用する必要がありますOpen

サイドノート:あなたの質問によると、私は動的クエリに固執しました。ただし、通常は、パラメーター化されたクエリまたはストアド プロシージャを使用することをお勧めします。

于 2015-02-25T17:20:00.883 に答える