ストアド プロシージャでの CONCAT ステートメントの実行が機能しない
P粉644981029
P粉644981029 2023-09-06 09:50:57
0
1
501

2 つのテーブルがあります。1 つは値 'tconst' (主キー) に関するさまざまな情報を含むベース テーブル、もう 1 つは 'titleId' という名前で 'nconst' からの複数の 'tconst' 値にリンクされているテーブルです。

---ベース テーブル 'titlebasics'

<テーブルクラス="s-テーブル"> <頭> tconst タイトルタイプ ... <みんな> tt0000009 映画 ... tt0000147 映画 ... ... ... ...

---追加情報テーブル 'knownfortitles'

<テーブルクラス="s-テーブル"> <頭> idnconst タイトル順タイトルID <みんな> 1nm00000011tt0050419 2nm00000012tt0053137 ... ... ... ...

「問題」は、knownfortitles.titleId の一部の値が titlebasics.tconst に存在しないことです。 2 つのテーブルと 2 つの対応する列の名前をパラメーターとして渡すことができるストアド プロシージャを作成したいと考えています。このプロセスでは、まず、最初のテーブルに存在しない値が実際に 2 番目のテーブルに存在するかどうかを確認し、存在する場合は、is_in_ という値を 2 番目のテーブルに追加します。リスト。その後、2 番目のテーブルの各行のブール値でこの列を更新します。この問題を抱えたテーブルがたくさんあり、異なる値を使用して同じコードを何度も記述するのではなく、このプロシージャを使用できるようにしたいため、これをストアド プロシージャで実行したいと考えています。しかし、プログラムを呼び出そうとするとエラーが発生し、修正できないようです。

ストアド プロシージャとしては、ここで行き詰まってしまいます。

CREATE PROCEDURE `CheckValueExistsInBaseTable`( INcheckedTable VARCHAR(100)、 IN 参照ベーステーブル VARCHAR(100)、 IN selectedCol VARCHAR(100)、 IN 参照列 VARCHAR(100) ) 始める DECLARE new_column_name VARCHAR(100) DEFAULT 'is_in_baseTable'; DECLARE sql_statement1 VARCHAR(1000) DEFAULT 'SELECT NULL;'; DECLARE sql_statement2 VARCHAR(1000) DEFAULT 'SELECT NULL;'; SET @new_column_name = CONCAT('is_in_',referencedBaseTable); -- チェックされたテーブルに新しい列が存在しない場合は追加します。 SET @sql_statement1 = CONCAT('IF (SELECT CASE WHEN EXISTS( 選択1 FROM '、checkedTable、' WHERE '、checkedCol、' NOT IN (SELECT '、referencedCol、' FROM '、referencedBaseTable、')) THEN 1 ELSE 0 終了 ) = 1 それから ALTER TABLE '、checkedTable、' ADD '、@new_column_name、' BOOL; それ以外 NULL を選択します。 END IF'); @sql_statement1 から stmt1 を準備します。 stmt1 を実行します。 DEALLOCATE PREPARE stmt1; -- チェックされたテーブルの is_in_referencedBaseTable 列を更新します SET @sql_statement2 = CONCAT('UPDATE ',checkedTable,'SET', @new_column_name, ' = CASE WHEN EXISTS(SELECT * FROM ', ReferencedBaseTable、' WHERE '、referencedBaseTable、'.'、 ReferencedCol、' = '、checkedTable、'.'、checkedCol、') THEN 1 ELSE 0 END'); @sql_statement2 から stmt2 を準備します。 stmt2 を実行します。 DEALLOCATE PREPARE stmt2; END

これ以上の変更は認められません、この都市は私たちの以下の説明の一つです。

<ブロック引用>

不正な SQL 手続きコード: 1064。 不正な SQL 手続きメソッドには不正な手続きがあります。不正な MySQL サーバー バージョンに対応する操作を確認し、最初の行「NULL」付近で使用される正しい手続きメソッドを確認してください。

または

<ブロック引用>

セキュリティコード: 1064。 問題のある SQL メソッドには問題があります。 問題のある MySQL サーバーのバージョンに対応する処理を検出し、 'IF (SELECT CASE WHEN EXISTS() 選択1 来自知名作品 WHERE titleId NOT' が最初の行にあります

私たちは、問題が発生する可能性のある部分を検査するためのプログラムも作成しましたが、両方ともうまく機能したため、さらに慎重になりました。中に入力されたコンテンツを調べて、そこに何らかの法的制限が存在するかどうかを確認します。

CREATE PROCEDURE `test`( INcheckedTable VARCHAR(100)、 IN 参照ベーステーブル VARCHAR(100)、 IN selectedCol VARCHAR(100)、 IN 参照列 VARCHAR(100)、 IN 新しい列名 VARCHAR (100) ) 始める -- 変数の宣言と値の代入 myvar VARCHAR(1000) を宣言します。 DECLARE new_column_name VARCHAR(100) DEFAULT 'is_in_baseTable'; SET @new_column_name = CONCAT('is_in_',referencedBaseTable); SET myvar = CONCAT('IF (存在する場合はケースを選択( 選択1 FROM '、checkedTable、' WHERE '、checkedCol、' NOT IN (SELECT '、referencedCol、' FROM '、referencedBaseTable、')) THEN 1 ELSE 0 終了 ) = 1 それから ALTER TABLE '、checkedTable、' ADD '、@new_column_name、' BOOL; それ以外 NULL を選択します。 END IF'); -- コンソールへの値の出力 SELECT concat(myvar) AS 変数; END

この过程次の結果:

IF (存在する場合は SELECT CASE( 選択1 来自知名作品 WHERE titleId が入っていない (titlebasics から tconst を選択)) THEN 1 ELSE 0 終了 ) = 1 それから ALTER TABLE knownfortitles ADD is_in_titlebasics BOOL; それ以外 NULL を選択します。 END IF

この段階のコードは明らかですが、これは次の 2 番目の手順を使用したためであることがわかります。この手順では、この厳密なコードが使用されています。

CREATE PROCEDURE `test2`() 始める IF (存在する場合はケースを選択( 選択1 来自知名作品 WHERE titleId が入っていない (titlebasics から tconst を選択)) THEN 1 ELSE 0 終了 ) = 1 それから ALTER TABLE knownfortitles ADD is_in_titlebasics BOOL; それ以外 NULL を選択します。 終了 IF; END

この过程将列 is_in_titlebasicsknownfortitles に追加しました。このとき、私は完全に迷ってしまい、結局のところ、最後の 2 つのプロセスの組み合わせであるため、自分の実際の保存プロセスが機能しないとは知りませんでした。忽略了我希望存您進行行的第 2 部分,因為我遇得错误幎最初の CONCAT

この句は問題です。

この問題が頻繁に起こることを望んでいますが、私たちは単に抜粋しただけです。

P粉644981029
P粉644981029

全員に返信 (1)
P粉798343415

P. Salmon のおかげで、プリペアド ステートメントを介してIF ... THENステートメントを実行することが問題であることが分かりました。不可能だよ。いくつかいじくり回した結果、希望どおりに動作する次のプログラムを思いつきました。私と同じような問題を抱えている人たちを助けることができれば幸いです。

リーリー

ただし、プログラムがエラーをスローしないようにするためにTRY ... CATCHなどを追加していないことを指摘しておきます。これは、機能させるための最低限のものです。

呼び出しプロセス

リーリー

返信メッセージの確認:

またはメッセージ警告:

最初のケースの場合のみ、TINYINT(1)列が必要に応じて追加されます。

いいねを押す+0
    最新のダウンロード
    詳細>
    ウェブエフェクト
    公式サイト
    サイト素材
    フロントエンドテンプレート
    私たちについて 免責事項 Sitemap
    PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!