вы создаете локальную переменную m1 в readfile. И тогда это отбрасывается, когда функция заканчивается. Возможно, вы хотите либо вернуть объект, либо установить текущий экземпляр
В подзапросе по сравнению с простыми (нерекурсивными) версиями CTE они, вероятно, очень похожи. Необходимо было бы использовать профилировщика и фактический план выполнения для определения любых различий, и это будет характерно для установки (таким образом, мы не сможем сказать Вам ответ полностью).
В целом; CTE может использоваться рекурсивно; подзапрос не может. Это делает их особенно хорошо подходящий для древовидных структур.
CTE
являются самыми полезными для рекурсии:
WITH hier(cnt) AS (
SELECT 1
UNION ALL
SELECT cnt + 1
FROM hier
WHERE cnt < @n
)
SELECT cnt
FROM hier
возвратится @n
строки (до 101
). Полезный для календарей, фиктивные наборы строк и т.д.
Они также более читаемы (по-моему).
Кроме этого, CTE
и subqueries
идентичны.
Если я не пропускаю что-то, можно назвать CTE's и подзапросы столь же легко.
Я предполагаю, что основным различием является удобочитаемость (я нахожу CTE более читаемым, потому что это определяет Ваш подзапрос впереди, а не в середине).
И если необходимо сделать что-нибудь с рекурсией, Вы собираетесь испытать немного затруднений при выполнении этого с подзапросом ;)
Основным преимуществом Общего Выражения Таблицы (если не использующий его для рекурсивных запросов) является инкапсуляция, вместо того, чтобы иметь необходимость объявить подзапрос в каждом месте, Вы хотите использовать его, Вы можете определить его однажды, но иметь несколько ссылок на него.
Однако это не означает, что выполняется только однажды (согласно предыдущим повторениям этого самого ответа, спасибо всем те, которые прокомментировали). Запрос определенно имеет потенциал, который будет выполняться многократно, если ссылается многократно; оптимизатор запросов в конечном счете принимает решение относительно того, как CTE должен быть интерпретирован.
Добавление к другим ответам, если у вас есть один и тот же подзапрос, используемый несколько раз, вы можете заменить все эти подзапросы одним CTE. Это позволяет лучше повторно использовать код.