Как подойти к процедурам и функциям MySQL

#mysql

#mysql

Вопрос:

Я опытный разработчик MS SQL. Переход с mssql на mysql немного расстраивает меня. Чтобы быть кратким, я хотел бы спросить, как выполняются некоторые стандартные задачи mssql в mysql. Самое первое, что я заметил, это то, что функция mysql не может вернуть набор результатов. В mssql тривиально использовать подобную функцию. В псевдокоде:

 CREATE FUNCTION fn_test()
RETURNS TABLE
AS
RETURN
SELECT * FROM SomeTable
  

И затем:

 SELECT * FROM table1 AS t1
INNER JOIN fn_test() AS fn ON t1.condition = fn.condition
  

Это невозможно в mysql, подход, который я нахожу после часа исследований, заключался в том, чтобы вместо этого создать процедуру, внутри создать временную таблицу, вставить в нее значения, после выполнения процедуры таблица остается «живой» на уровне соединения, а затем удалить таблицу. Мне кажется, что это накладные расходы. Итак, вопросы здесь:

1) Если это, скажем, 500 подключений, и все эти подключения выполняют, скажем, 2-3 процедуры, используя подход, о котором я упоминал, это означает, что 500×1 временных таблиц x2 вызовов процедур = 1000 временных таблиц. Как сервер будет обрабатывать эту технику?

2) Является ли это единственным подходом, и есть ли что-то лучше, чем этот, например, по представлениям или чему-то еще?

3) Какой подход вы выбираете для этого конкретного сценария?

Ответ №1:

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

Однако в MySQL есть концепция пользовательских функций или UDF.. Подробнее ЗДЕСЬ Предоставлено, что временная таблица может быть отличным вариантом, но в вашем случае вам может потребоваться создать свою собственную функцию.

Вот еще одна ссылка на функции и операторы MySQL ЗДЕСЬ

РЕДАКТИРОВАТЬ: Чтобы ответить на ваш вопрос, вам нужно будет использовать сохраненную процедуру для возврата таблицы в MySQL.

 DELIMITER $$

 CREATE DEFINER=`root`@`%` PROCEDURE `ret_table`(OUT my_ErrMessage   VARCHAR(200))
 BEGIN
 DECLARE EXIT HANDLER FOR SQLEXCEPTION
 BEGIN
SET my_ErrMessage = 'Error in procedure ret_table';
 END;

 SELECT * FROM SomeTable;
END
  

Я добавлю, что более 500 подключений и более 1000 временных таблиц не являются чем-то необычным в средах БД, если только ваши временные таблицы не очень большие. Кроме того, таблица возврата через вызов функции не сильно отличается от временной таблицы в том, что касается памяти. Вы не упоминаете никаких функциональных требований выше, только теоретическую проблему невозможности возврата таблицы с помощью вызова функции.

Наконец, я совсем не против MS, но при использовании их инструментов разработки в Windows очень легко размыть границы между тем, какую работу вы обычно выполняете на прикладном уровне, и тем, какую работу вы выполняете в базе данных. MySQL не будет MS SQL Server или Oracle, но он будет делать то, что вам нужно. Вам просто нужно подойти к решению проблем по-другому.

Я бы сделал это:

 CREATE TEMPORARY TABLE IF NOT EXISTS someTab1 AS (SELECT * FROM SomeTable);

SELECT * FROM table1 AS t1
INNER JOIN someTab1 AS st1 ON t1.condition = st1.condition
  

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

Комментарии:

1. спасибо за ответ, но все же это не тот ответ, который я искал, пожалуйста, проверьте вопросы 1), 2), 3). Мне кажется, что с помощью UDF я не могу выполнить задачу, на которую я был нацелен: 1: UDF не может возвращать таблицу, к которой я могу присоединиться позже с другой таблицей. 2. Подход с вызовами процедур и временными таблицами по-прежнему остается единственным вариантом, но как насчет производительности при использовании этого метода?

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