Rumah  >  Soal Jawab  >  teks badan

Melaksanakan pernyataan CONCAT dalam prosedur tersimpan tidak berfungsi

<p>Saya mempunyai dua jadual, jadual asas yang mengandungi pelbagai maklumat tentang nilai 'tconst' (juga kunci utama) dan satu lagi jadual yang dipautkan kepada berbilang nilai 'tconst' daripada 'nconst' di bawah nama 'titleId' . </p> <p>---Jadual asas 'titlebasics'</p> <table class="s-table"> <kepala> <tr> <th>tconst</th> <th>Jenis Tajuk</th> <th>...</th> </tr> </kepala> <tbody> <tr> <td>tt0000009</td> <td>Filem</td> <td>...</td> </tr> <tr> <td>tt0000147</td> <td>Filem</td> <td>...</td> </tr> <tr> <td>...</td> <td>...</td> <td>...</td> </tr> </tbody> </table> <p>---Jadual maklumat tambahan 'knownfortitles'</p> <table class="s-table"> <kepala> <tr> <th>id</th> <th>nconst</th> <th>Turutan Tajuk</th> <th>ID Tajuk</th> </tr> </kepala> <tbody> <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> </tbody> </table> <p>"Masalah" ialah beberapa nilai dalam <code>knownfortitles.titleId</code> tidak wujud dalam <code>titlebasics.tconst</code>. Saya ingin mencipta prosedur tersimpan di mana saya boleh menghantar sebagai parameter nama dua jadual dan dua lajur yang sepadan. Proses ini terlebih dahulu akan menyemak sama ada nilai yang tidak wujud dalam jadual pertama benar-benar wujud dalam jadual kedua, dan jika ya, tambahkan jadual baharu pada jadual kedua bernama <code>is_in_<base_table_name</code> . Ia kemudiannya akan mengemas kini lajur ini dengan nilai boolean daripada setiap baris dalam jadual kedua. Saya ingin melakukan ini dalam prosedur tersimpan kerana saya mempunyai banyak jadual dengan masalah ini dan saya mahu dapat menggunakan prosedur ini dan bukannya menulis kod yang sama berulang kali dengan nilai yang berbeza.Walau bagaimanapun, saya mendapat ralat apabila saya cuba memanggil program saya dan saya nampaknya tidak dapat membetulkannya. </p> <p>Sebagai prosedur tersimpan, di sinilah saya terjebak. </p> <pre class="brush:php;toolbar:false;">BUAT PROSEDUR `CheckValueExistsInBaseTable`( DALAM Jadual ditandai VARCHAR(100), DALAM referencedBaseTable VARCHAR(100), DALAM ditandaiCol VARCHAR(100), DALAM rujukanCol VARCHAR(100) ) BERMULA DECLARE new_column_name VARCHAR(100) LAILA 'adalah_dalam_baseTable'; DECLARE sql_statement1 VARCHAR(1000) LAILA 'SELECT NULL;'; DECLARE sql_statement2 VARCHAR(1000) LAILA 'SELECT NULL;'; SET @new_column_name = CONCAT('is_in_',referencedBaseTable); -- Tambah lajur baharu pada jadual yang disemak jika ia tidak wujud SET @sql_statement1 = CONCAT('JIKA (PILIH KES APABILA WUJUD( Pilih 1 DARI ', CheckedTable, ' DI MANA ', checkedCol, ' NOT IN (SELECT ', referencedCol, ' FROM ', referencedBaseTable, ')) KEMUDIAN 1 LAIN 0 TAMAT ) = 1 KEMUDIAN ALTER JADUAL ', checkedTable, ' ADD ', @new_column_name, ' BOOL; LAIN PILIH NULL; TAMAT JIKA'); SEDIAKAN stmt1 DARI @sql_statement1; MELAKSANAKAN stmt1; NYATAKAN PERUNTUKAN SEDIAKAN stmt1; -- Kemas kini lajur is_in_referencedBaseTable dalam jadual yang diperiksa SET @sql_statement2 = CONCAT('KEMASKINI ', jadual yang ditanda, ' SET ', @new_column_name, ' = KES BILA WUJUD(PILIH * DARI ', referencedBaseTable, ' WHERE ', referencedBaseTable, '.', referencedCol, ' = ', checkedTable, '.', checkedCol, ') MAKA 1 LAIN 0 TAMAT'); SEDIAKAN stmt2 DARI @sql_statement2; MELAKSANAKAN stmt2; DEALLOCATE PREPARE stmt2; TAMAT</pra> <p>Tidak kira apa yang saya cuba ubah, ini memberi saya salah satu daripada ralat berikut. </p> <blockquote> <p>Kod ralat: 1064. Terdapat ralat dalam sintaks SQL anda semak manual untuk versi pelayan MySQL anda untuk sintaks yang betul untuk digunakan berhampiran "NULL" pada baris 1</p> </blockquote> <p> atau </p> <blockquote> <p>Kod ralat: 1064. Terdapat ralat dalam sintaks SQL anda semak manual untuk versi pelayan MySQL anda untuk mengetahui cara menggunakan 'IF (SELECT CASE WHEN EXISTS(; Pilih 1 Daripada karya terkenal WHERE titleId NOT' pada baris 1</p> </blockquote> <p>Saya juga mencipta program ujian untuk menyemak bahagian mana yang mungkin mengalami masalah, tetapi kedua-duanya berfungsi dengan baik, yang lebih mengelirukan saya. Yang pertama hanya mengembalikan apa yang saya masukkan ke dalam <code>CONCAT</code> untuk melihat jika terdapat sebarang ralat sintaks di dalamnya.</p> <pre class="brush:php;toolbar:false;">BUAT PROSEDUR `test`( DALAM Jadual ditandai VARCHAR(100), DALAM referencedBaseTable VARCHAR(100), DALAM ditandaiCol VARCHAR(100), DALAM rujukanCol VARCHAR(100), IN new_column_name VARCHAR (100) ) BERMULA -- Mengisytiharkan pembolehubah dan memberikan nilai mengisytiharkan myvar VARCHAR(1000); DECLARE new_column_name VARCHAR(100) LAILA 'adalah_dalam_baseTable'; SET @new_column_name = CONCAT('is_in_',referencedBaseTable); SET myvar = CONCAT('JIKA (PILIH KES APABILA WUJUD( 选择1 DARI ', CheckedTable, ' DI MANA ', checkedCol, ' NOT IN (SELECT ', referencedCol, ' FROM ', referencedBaseTable, ')) KEMUDIAN 1 LAIN 0 TAMAT ) = 1 KEMUDIAN ALTER JADUAL ', checkedTable, ' ADD ', @new_column_name, ' BOOL; LAIN PILIH NULL; TAMAT JIKA'); -- Mencetak nilai ke konsol PILIH concat(myvar) SEBAGAI Pembolehubah; TAMAT</pra> <p>此过程给出下一个结果:</p> <pre class="brush:php;toolbar:false;">JIKA (PILIH KES BILA WUJUD( 选择1 来自知名作品 WHERE titleId NOT IN (SELECT tconst FROM titlebasics)) KEMUDIAN 1 LAIN 0 TAMAT ) = 1 KEMUDIAN ALTER TABLE yang diketahui untuk tajuk ADD is_in_titlebasics BOOL; LAIN PILIH NULL; TAMAT JIKA</pra> <p>这段代码是正确的,我知道这一点是因为我使用了下面的第二个过程,用了过程,管了切的代码块。</p> <pre class="brush:php;toolbar:false;">BUAT PROSEDUR `test2`() BERMULA JIKA (PILIH KES BILA WUJUD ( 选择1 来自知名作品 WHERE titleId NOT IN (SELECT tconst FROM titlebasics)) KEMUDIAN 1 LAIN 0 TAMAT ) = 1 KEMUDIAN ALTER TABLE yang diketahui untuk tajuk ADD is_in_titlebasics BOOL; LAIN PILIH NULL; TAMAT JIKA; TAMAT</pra> <p>此过程将列 <kod>is_in_titlebasics</code> 添加到表 <kod>knownfortitles</code> 中,这就是我想要发生的事情,所以这很好。此时,我完全迷失了,不知道为什们乭为起作用,因为它基本上是最后两个过程的组合。我暂时忽略了我希望存储过程执行的第二部分,因为我遇到的错误似乎将第一个/ <code&t;CAT&g个; 语句视为问题。</p> <p>我希望这个问题是非常明显的,但我只是忽略了。欢迎任何帮助,提/前;g!
P粉644981029P粉644981029410 hari yang lalu557

membalas semua(1)saya akan balas

  • P粉798343415

    P粉7983434152023-09-07 00:02:02

    Terima kasih kepada P. Salmon, saya mengetahui bahawa masalah sedang berjalan IF ... THEN kenyataan melalui kenyataan yang disediakan. Ini adalah mustahil. Selepas beberapa kali bermain-main, saya datang dengan program berikut, yang berfungsi tepat seperti yang saya mahu. Saya harap saya dapat membantu beberapa orang yang mempunyai masalah yang sama dengan saya.

    DELIMITER $$
    USE `<schema>`$$
    CREATE DEFINER=`Setupinfolab`@`%` PROCEDURE `CheckValueExistsInBaseTable`(
        IN checkedTable VARCHAR(100),
        IN referencedBaseTable VARCHAR(100),
        IN checkedCol VARCHAR(100),
        IN referencedCol VARCHAR(100)
        )
    BEGIN
        SET @checkedTable = checkedTable;
        SET @referencedBaseTable = referencedBaseTable;
        SET @checkedCol = checkedCol;
        SET @referencedCol = referencedCol;
        SET @new_column_name  = CONCAT('is_in_', referencedBaseTable);
        
        -- Check if there are indeed values in checkedCol that are not present in referencedCol
        SET @query1 = CONCAT('
            SELECT CASE WHEN EXISTS(
                SELECT 1 
                FROM ',@checkedTable,'
                WHERE ',@checkedCol,' NOT IN (SELECT ',@referencedCol,' FROM ',@referencedBaseTable,')) 
                THEN 1 ELSE 0 END 
                INTO @proceed');
            
        -- Adding the boolean column
        SET @query2 = CONCAT('
            ALTER TABLE ',@checkedTable,' ADD ',@new_column_name,' BOOL;');
        
        -- Inserting boolean values in new column according to presence in referencedCol
        SET @query3 = CONCAT('
            UPDATE ',@checkedTable,' SET ',@new_column_name,' = (
                CASE WHEN EXISTS(
                    SELECT * 
                    FROM ',@referencedBaseTable,' 
                    WHERE ',@referencedBaseTable,'.',@referencedCol,' = ',@checkedTable,'.',@checkedCol,')
                THEN true ELSE false END
                ) WHERE id<>0;');
        
        PREPARE stmt1 FROM @query1;
        EXECUTE stmt1;
        
        IF @proceed = 1
        THEN 
            PREPARE stmt2 FROM @query2;
            EXECUTE stmt2;
            PREPARE stmt3 FROM @query3;
            EXECUTE stmt3;
            SELECT CONCAT(@new_column_name,' column added to table ', @checkedTable,'.') 
                AS 'Message: Done';
            DEALLOCATE PREPARE stmt2;
            DEALLOCATE PREPARE stmt3;
        ELSE 
            SELECT 'All values are present in base table. Adding column is thus unnecessary.' 
                AS 'Message: UNNECESSARY';
        END IF;
        
        DEALLOCATE PREPARE stmt1;
    END$$
    DELIMITER ;
    ;

    Walau bagaimanapun, saya ingin menyatakan bahawa saya tidak menambah TRY ... CATCH atau apa-apa untuk menghalang program daripada membuang ralat. Ini hanyalah minimum untuk menjadikannya berfungsi.

    Proses panggilan

    CALL CheckValueExistsInBaseTable(
        'knownfortitles',
        'titlebasics',
        'titleId',
        'tconst'
        );

    Pengesahan mesej balas:

    atau mesej amaran:

    Hanya dalam kes pertama, TINYINT(1) lajur akan ditambah mengikut keperluan.

    balas
    0
  • Batalbalas