Хранимая процедура для ввода данных в таблицу, где данные и имя таблицы являются динамическими

0

Я использовал следующий код, и я не могу найти, где я ошибаюсь. Я выполняю следующий код, говорящий об ошибке в sql-синтаксисе. Пожалуйста, помогите мне, я новичок в mysql и хранимых процедурах. Ошибка, которую я получаю: Код ошибки 1064, У вас есть синтаксическая ошибка sql.

         CREATE DEFINER='PotatoHead'@'%' PROCEDURE 'InsertIntoTable'(in    
            tablename varchar(45),in ID varchar(45),in Project 
            varchar(45),in Variant varchar(45)
            in ReleaseVersion varchar(45) ,
            in TestBenchID varchar(45) ,
            in TestCaseID int(11) ,
            in TestCaseNamespace varchar(100) ,
            in TestCaseName varchar(45),
            in TestCaseDomain varchar(45) ,
            in TestType varchar(45) ,
            in HardwareVersion varchar(4000) ,
            in SoftwareVersion varchar(4000),
            in Result varchar(45) ,
            in Comment varchar(4000),
            in Duration varchar(45) ,
            in StartTime varchar(45) ,
            in EndTime varchar(45)  )
  BEGIN

  SET @sql = CONCAT('Insert into ', tablename ,' (ID,Project,Variant,
            ReleaseVersion,
            TestBenchID ,
            TestCaseID ,
            TestCaseNamespace ,
            TestCaseName ,
            TestCaseDomain ,
            TestType ,
            HardwareVersion ,
            SoftwareVersion ,
            Result ,
            Comment ,
            Duration ,
            StartTime ,
            EndTime) VALUES (');
    SET @sql = CONCAT(ID,',',Project,',',Variant,',',
    ReleaseVersion,',',
    TestBenchID,',',
    TestCaseID,',',
    TestCaseNamespace ,',',
    TestCaseName ,',',
    TestCaseDomain ,',',
    TestType ,',',
    HardwareVersion ,',',
    SoftwareVersion ,',',
    Result ,',',
    Comment ,',',
    Duration ,',',
    StartTime ,',',
    EndTime,');');
PREPARE s FROM @sql;
EXECUTE s;
DEALLOCATE PREPARE s;



 END
Теги:
stored-procedures

1 ответ

1

У вас есть небольшая опечатка, отсутствует запятая в вашем списке входных параметров после

in Variant varchar(45)
                      ^^^^

Это полное сообщение об ошибке, которое я получил, когда я запустил ваш код в Workbench

Код ошибки: 1064. У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с 'в ReleaseVersion varchar (45), в TestBenchID varchar (45),' в строке 6

Вы отредактировали часть сообщения об ошибке, которое сообщило бы вам, где искать ошибку, которая будет перед цитируемым кодом.

Кроме того, если вы еще этого не сделали, вам нужно сбросить DELIMITER до и после определения процедуры с несколькими заявками, чтобы MySQL знал, как обрабатывать все определение как одно.

например

DELIMITER //

CREATE DEFINER='PotatoHead'@'%' PROCEDURE 'InsertIntoTable'() 
BEGIN
  Your proc definition
END 
//

DELIMITER ;

Обновить

Это последнее изменение должно быть скомпилировано, так что теперь мы сталкиваемся с ошибками во время выполнения. Признаюсь, я не смотрел выше первой ошибки на вашем исходном коде, поэтому не заметил некоторых других проблем. например

  • множественное присвоение переменной @sql, а не конкатенация
  • неучтенные строки в списке значений, полученных в результате concat
  • повторное использование имен столбцов для параметров (вы бы с ним справились, но могут привести к неожиданным результатам)
  • однако, большая вещь, которую я пропустил, - это то, почему вы даже захотите использовать динамический SQL для этой проблемы в первую очередь, это просто не нужно, если имя таблицы не изменится.

Позвольте взять их в порядок:

Вы назначаете первую часть инструкции INSERT для @sql. Это здорово. Позже вы назначаете список VALUES одной и той же переменной. На этом этапе вы заменяете оригинал, а не объединяете две части. Это вызывает вторую ошибку, которую вы опубликовали. Вы исправите это

SET @sql = CONCAT(@sql,' VALUES(' etc.

Оператор CONCAT собирается оставить вас с строкой, содержащей 16 переменных без кавычек для столбцов VARCHAR. Вам нужно будет включить одинарные кавычки во всех этих значениях, или инструкция PREPARE завершится с ошибкой. Вы исправите это

SET @sql = CONCAT(@sql, '\'',
    ID,'\',\'',
    Project,'\',\'',
    Variant,'\',\'',
    ReleaseVersion,'\',\'',
    TestBenchID,'\',\'',
    TestCaseID,',',
    TestCaseNamespace ,'\',\'',

и т.п.

Теперь CONCAT становится немного грязным, я думаю, вы согласитесь.

Затем возникает вопрос об использовании тех же имен для ваших параметров и имен столбцов в вашей таблице. Как я уже говорил, в этом случае вы избегаете этого, однако MySQL будет определять приоритет имени параметра над именем столбца, когда он определяет, что используется, и это может привести к проблемам, когда параметры используются в предложении SELECT, WHERE, и т.д. Хорошая практика заключается в том, чтобы различать их, чтобы избежать путаницы. Поэтому я также переименовал бы все ваши параметры. например

 CREATE PROCEDURE 'InsertIntoTable' (
    in _tablename varchar(45),
    in _ID varchar(45),
    in _Project varchar(45),
    in _Variant varchar(45),
    in _ReleaseVersion varchar(45) ,

и затем соответствующим образом обновить список VALUES. BTW, так как все ваши входные параметры являются параметрами IN, а по умолчанию вы можете обойтись без "in" перед каждым и сохранить себе некоторую типизацию.

Наконец, использование динамического SQL. Я подозреваю, что эта процедура записывается во все столбцы таблицы и что есть только одна таблица с этим точным определением. Если имя таблицы не изменится, почему нужно иметь возможность изменять ее во время выполнения? Если это не так, какова ваша причина иметь несколько таблиц для хранения одних и тех же данных? Если мое подозрение правильное, тогда вы можете полностью использовать динамический SQL, и процедура будет намного проще

например

CREATE PROCEDURE 'InsertIntoYrTablename' (
    _ID varchar(45),
    _Project varchar(45),
    _Variant varchar(45),
    _ReleaseVersion varchar(45),
    _TestBenchID varchar(45),
    _TestCaseID int(11),
    _TestCaseNamespace varchar(100),
    _TestCaseName varchar(45),
    _TestCaseDomain varchar(45),
    _TestType varchar(45),
    _HardwareVersion varchar(4000),
    _SoftwareVersion varchar(4000),
    _Result varchar(45),
    _Comment varchar(4000),
    _Duration varchar(45),
    _StartTime varchar(45),
    _EndTime varchar(45))
  INSERT into 'yrtablename' (
    ID,
    Project,
    Variant,
    ReleaseVersion,
    TestBenchID,
    TestCaseID,
    TestCaseNamespace,
    TestCaseName,
    TestCaseDomain,
    TestType,
    HardwareVersion,
    SoftwareVersion,
    Result,
    Comment,
    Duration,
    StartTime,
    EndTime
  ) VALUES (
    _ID,
    _Project,
    _Variant,
    _ReleaseVersion,
    _TestBenchID,
    _TestCaseID,
    _TestCaseNamespace,
    _TestCaseName,
    _TestCaseDomain,
    _TestType,
    _HardwareVersion,
    _SoftwareVersion,
    _Result,
    _Comment,
    _Duration,
    _StartTime,
    _EndTime);

Это намного легче читать и поддерживать и выполнять эту работу без проблемных манипуляций с строками. MySQL позаботится о том, чтобы указывать параметры для вас, и потому, что теперь это один оператор, обойтись без необходимости блокировать BEGIN... END и сбросить DELIMITER.

  • 0
    Он все еще не работает, он говорит код ошибки 1064, ошибка рядом с синтаксисом «ID, проект, версия» в строке 1
  • 0
    @vidhik Смотрите мои изменения для вашей ошибки.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню