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

Я использовал следующий код, и я не могу найти, где я иду не так. Я выполняю следующий код, который говорит об ошибке в синтаксисе 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

1 Ответ

0 голосов
/ 27 мая 2018

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

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 оставит строку you, содержащую 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) ,

, а затем соответствующим образом обновите список ЗНАЧЕНИЙ.Кстати, так как все ваши входные параметры являются параметрами 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...