Как заставить SSMS использовать относительный путь текущего скрипта с: r в режиме sqlcmd, как это делает SSDT?

11

Если у меня есть foo.sql и bar.sql в одной папке, foo.sql может ссылаться на bar.sql при запуске из SSDT в режиме sqlcmd с :r ".\bar.sql". Однако SSMS не найдет его. Procmon показывает, что SSMS ищет %systemroot%\syswow64:

Аннотированный скриншот Procmon

Как сказать SSMS искать в папке, в которой текущий скрипт сохраняется, без явного объявления пути?

Джастин Даринг
источник

Ответы:

8

Получить относительный путь в SSMS не так просто, так как вы не выполняете сценарий; SSMS загрузила скрипт в память и выполняет его текст. Таким образом, текущий каталог / папка является начальной папкой процесса по умолчанию. Вы можете убедиться в этом, запустив в SSMS в режиме SQLCMD следующее:

!! PWD

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

Итак, что вы можете сделать, это:

  1. Выполните команду DOS, чтобы найти foo.sql и сохранить путь к этому файлу в текстовом файле в папке, которую вы можете получить из SSMS, либо потому, что это жестко заданный путь, либо потому, что он использует переменную среды, доступную для и команда DOS, и режим SQLCMD в SSMS
  2. При сохранении пути в этом файле сохраните его как команду режима SQLCMD, которая устанавливает переменную в этот путь
  3. Импортируйте этот текстовый файл в SSMS с помощью, :rи он установит эту переменную по желаемому пути
!! CD C:\ & FOR /F %B IN ('DIR /B /A -HS /S foo.sql') DO ECHO :setvar mypath "%~dpB" > %TEMP%\relative_path.txt

:r $(TEMP)\relative_path.txt

:r $(mypath)\bar.sql

Заметки:

  • Приведенный выше метод предполагает, что только один файл в системе называется foo.sql . Если более чем один файл имеет это имя, последний найденному будет набором пути в relative_path.txt файл

  • Выполнение CD C:\начнется в корне диска C : . Вероятно, это не самое эффективное место для начала. Если у вас обычно есть файлы SQL в такой области, как C: \ Users {YourLogin} \ Documents \ Visual Studio 2013 \ Projects , просто измените CDкоманду, чтобы приблизиться к месту назначения, например:

    !! CD C:\Users\{YourLogin}\Documents\Visual Studio 2013 & FOR ...
Соломон Руцкий
источник
Это креативно, но медленно и интенсивно использует диск.
Джастин Даринг
2
@JustinDearing Как я уже сказал в своем ответе, это а) неидеально и б) медленно, если начинать с корневого каталога, но в) единственный способ, которым я могу сделать это, является технически относительным. Я не уверен, что индексирование жесткого диска устранит проблему с производительностью.
Соломон Руцкий,
Хотя это меня огорчает, но, безусловно, это лучший ответ, который не требует установки пути из другого командного сценария или жесткого кодирования его в файл.
QueueHammer
5

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

/programming/8753541/how-to-get-the-relative-path-of-file-in-sqlcmd-mode-in-ssms

http://boardreader.com/thread/Specifying_relative_path_to_r_command_in_lmlz__f0c78408-e001-48a2-8369-338c9534f496.html

SQL Hammer
источник
Хорошо, это отстой, но я думаю, что это поощряет использование SSDT.
Джастин Даринг
2

Я рекомендую сохранить файл переменных sqlcmd в «C: \ Users \ your_nt_login_name \ AppData \ Local \ Temp» и ссылаться на него из всех моих проектов как $ (TEMP) \ sqlcmd_variables.sql.

Вернон Джиммерсон
источник