L'exécution de l'instruction CONCAT dans une procédure stockée ne fonctionne pas
P粉644981029
2023-09-06 09:50:57
<p>J'ai deux tables, une table de base contenant diverses informations sur la valeur 'tconst' (également la clé primaire) et une autre table liée à plusieurs valeurs 'tconst' de 'nconst' sous le nom 'titleId' . </p>
<p>---Table de base 'titlebasics'</p>
<table class="s-table">
<tête>
<tr>
<th>tconst</th>
<th>Type de titre</th>
<th>...</th>
≪/tr>
≪/tête>
<corps>
<tr>
<td>tt0000009</td>
<td>Films</td>
<td>...</td>
≪/tr>
<tr>
<td>tt0000147</td>
<td>Films</td>
<td>...</td>
≪/tr>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
≪/tr>
</tcorps>
</tableau>
<p>---Tableau d'informations supplémentaires 'knownfortitles'</p>
<table class="s-table">
<tête>
<tr>
<th>id</th>
<th>ncconst</th>
<th>Ordre des titres</th>
<th>ID du titre</th>
≪/tr>
≪/tête>
<corps>
<tr>
<td>1</td>
<td>nm0000001</td>
<td>1</td>
<td>tt0050419</td>
≪/tr>
<tr>
<td>2</td>
<td>nm0000001</td>
<td>2</td>
<td>tt0053137</td>
≪/tr>
<tr>
<td>...</td>
<td>...</td>
<td>...</td>
<td>...</td>
≪/tr>
</tcorps>
</tableau>
<p>Le "problème" est que certaines valeurs de <code>knownfortitles.titleId</code> n'existent pas dans <code>titlebasics.tconst</code>. Je souhaite créer une procédure stockée dans laquelle je peux passer en paramètres les noms de deux tables et de deux colonnes correspondantes. Ce processus vérifiera d'abord si la valeur qui n'existe pas dans la première table existe réellement dans la deuxième table et, si c'est le cas, ajoutera une nouvelle table à la deuxième table nommée <code>is_in_<base_table_name></code> . Il mettra ensuite à jour cette colonne avec la valeur booléenne de chaque ligne du deuxième tableau. Je souhaite faire cela dans une procédure stockée car j'ai beaucoup de tables avec ce problème et je veux pouvoir utiliser cette procédure au lieu d'écrire encore et encore le même code avec des valeurs différentes.Cependant, j'obtiens une erreur lorsque j'essaie d'appeler mon programme et je n'arrive pas à la corriger. </p>
<p>En tant que procédure stockée, c'est là que je suis bloqué. </p>
<pre class="brush:php;toolbar:false;">CRÉER UNE PROCÉDURE `CheckValueExistsInBaseTable`(
DANS table vérifiée VARCHAR(100),
DANS referencedBaseTable VARCHAR(100),
DANS vérifiéCol VARCHAR(100),
IN référencéCol VARCHAR(100)
)
COMMENCER
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);
-- Ajouter une nouvelle colonne au tableau coché si elle n'existe pas
SET @sql_statement1 = CONCAT('IF (SELECT CASE WHEN EXISTS(
Choisir 1
FROM ', table vérifiée, '
OÙ ', col vérifié, ' PAS DANS (SELECT ', col référencé, ' FROM ', tableBase référencée, '))
PUIS 1 AUTRE 0 FIN
) = 1
ALORS
ALTER TABLE ', vérifiéTable, ' ADD ', @new_column_name, ' BOOL;
AUTRE
SÉLECTIONNEZ NULL ;
FIN SI');
PRÉPARER stmt1 FROM @sql_statement1 ;
EXÉCUTER stmt1 ;
DÉSALLOCATION PREPARE stmt1 ;
-- Mettre à jour la colonne is_in_referencedBaseTable dans la table cochée
SET @sql_statement2 = CONCAT('MISE À JOUR', table vérifiée, 'SET',
@new_column_name, ' = CASE QUAND EXISTE (SELECT * FROM ',
referencedBaseTable, ' OÙ ', referencedBaseTable, '.',
referencedCol, ' = ', CheckTable, '.', CheckCol, ') THEN 1 ELSE 0 END');
PRÉPARER stmt2 FROM @sql_statement2 ;
EXÉCUTER stmt2 ;
DÉSALLOCATION PREPARE stmt2 ;
FIN</pré>
<p>Peu importe ce que j'essaie de modifier, cela me donne l'une des erreurs suivantes. </p>
<blockquote>
<p>Code d'erreur : 1064. Il y a une erreur dans votre syntaxe SQL ; consultez le manuel de la version de votre serveur MySQL pour connaître la syntaxe correcte à utiliser près de "NULL" à la ligne 1</p>
</blockquote>
<p> ou </p>
<blockquote>
<p>Code d'erreur : 1064. Il y a une erreur dans votre syntaxe SQL ; consultez le manuel de la version de votre serveur MySQL pour savoir comment utiliser 'IF (SELECT CASE WHEN EXISTS(
Choisir 1
D'œuvres connues
OÙ titleId NOT' sur la ligne 1</p>
</blockquote>
<p>J'ai également créé des programmes de test pour vérifier quelles pièces pourraient rencontrer des problèmes, mais les deux fonctionnent correctement, ce qui me rend encore plus confus. Le premier renvoie simplement ce que j'ai mis dans <code>CONCAT</code> pour voir s'il contient des erreurs de syntaxe.</p>
<pre class="brush:php;toolbar:false;">CRÉER UNE PROCÉDURE `test`(
DANS table vérifiée VARCHAR(100),
DANS referencedBaseTable VARCHAR(100),
DANS vérifiéCol VARCHAR(100),
IN référencéCol VARCHAR(100),
DANS new_column_name VARCHAR (100)
)
COMMENCER
-- Déclarer la variable et attribuer la valeur
déclarer mavar VARCHAR(1000);
DECLARE new_column_name VARCHAR(100) DEFAULT 'is_in_baseTable';
SET @new_column_name = CONCAT('is_in_',referencedBaseTable);
SET mavar = CONCAT('IF (SELECT CASE WHEN EXISTS(
Étape 1
FROM ', table vérifiée, '
OÙ ', col vérifié, ' PAS DANS (SELECT ', col référencé, ' FROM ', tableBase référencée, '))
PUIS 1 AUTRE 0 FIN
) = 1
ALORS
ALTER TABLE ', vérifiéTable, ' ADD ', @new_column_name, ' BOOL;
AUTRE
SÉLECTIONNEZ NULL ;
FIN SI');
-- Impression de la valeur sur la console
SELECT concat(myvar) AS Variable ;
FIN</pré>
<p>此过程给出下一个结果:</p>
<pre class="brush:php;toolbar:false;">IF (SELECT CASE WHEN EXISTS(
Étape 1
来自知名作品
OÙ titleId NOT IN (SELECT tconst FROM titlebasics))
PUIS 1 AUTRE 0 FIN
) = 1
ALORS
ALTER TABLE knownfortitles ADD is_in_titlebasics BOOL;
AUTRE
SÉLECTIONNEZ NULL ;
FIN SI</pre>
<p>确切的代码块。</p>
<pre class="brush:php;toolbar:false;">CRÉER UNE PROCÉDURE `test2`()
COMMENCER
SI (SELECT CAS QUAND EXISTE (
Étape 1
来自知名作品
OÙ titleId NOT IN (SELECT tconst FROM titlebasics))
PUIS 1 AUTRE 0 FIN
) = 1
ALORS
ALTER TABLE knownfortitles ADD is_in_titlebasics BOOL;
AUTRE
SÉLECTIONNEZ NULL ;
FIN SI;
FIN</pré>
<p>此过程将列 <code>is_in_titlebasics</code> 添加到表 <code>knownfortitles</code> 中,这就是我想要发生的事情,所以这很好。此时,我完全迷失了,不知道为什么我的实际存储过程不起作用,因为它基本上是最后两个过程的组合。我暂时<code>CONCAT</code> 语句视为问题。</p>
<p>
Grâce à P. Salmon, j'ai appris que le problème résidait dans l'exécution des
IF ... THEN
instructions à travers des instructions préparées. C'est impossible. Après quelques réflexions, j'ai trouvé le programme suivant, qui fonctionne exactement comme je le souhaite. J'espère pouvoir aider certaines personnes qui ont des problèmes similaires aux miens.Cependant, je tiens à souligner que je n'ai pas ajouté
TRY ... CATCH
ou quoi que ce soit pour empêcher le programme de générer une erreur. Ce n’est que le strict minimum pour que cela fonctionne.Processus d'appel
Confirmation du message de retour :
ou message d'avertissement :
Seulement dans le premier cas, les colonnes
TINYINT(1)
seront ajoutées selon les besoins.