Эхо литеральная строка?

У меня есть процедура SQL, которая вызывает командную оболочку для записи дампа SQL в файл. Возьмем, к примеру, этот отредактированный файл:

VALUES(
  @SomeVar
  ,1
)

Процедура вызывает:

echo VALUES(>> C:\somefile.sql
echo @SomeVar>> C:\somefile.sql
echo ,1>> C:\somefile.sql
echo )>> C:\somefile.sql

Это отлично работает, за исключением строки ,1. Если вы запустите echo ,1>> C:\somefile.sql в CMD, вы увидите, что C:\somefile.sql содержит только ,

Моя теория состоит в том, что echo думает, что может принимать более 1 параметра.

Если вы измените команду на echo ,1blah>> C:\somefile.sql, она отлично работает.

Я мог бы изменить свою процедуру, чтобы проверить, содержит ли строка ,, за которой следует число, за которым не следует ничего, и добавить ^ к числу, чтобы избежать его. Хотя это немного больно.

Также echo 1>> C:\somefile.sql пишет Echo is ON

Есть ли способ echo буквальной строки в CMD? Включение строки в " " выводит метки ". Или есть какое-то другое решение, о котором вы можете подумать?


person Danny Beckett    schedule 04.09.2012    source источник


Ответы (4)


Проблема в том, что 1 является дескриптором файла для стандартного потока вывода в пакетных файлах / CMD.EXE. Вы можете обойти это, используя вместо этого эту строку:

echo ,1 1>> C:\somefile.sql

Или, что более хрупко, просто поставьте пробел между перенаправлением 1 и >>.

echo ,1 >> C:\Somefile.sql

Обновление: если вас действительно беспокоят конечные пробелы в приведенных выше примерах, вы также можете использовать

>> C:\Somefile.sql echo ,1

т.е. вы также можете поместить перенаправление перед командой. Лично мне это кажется немного несуразным, но YMMV.

person Christian.K    schedule 04.09.2012
comment
Но это не проблема правильного синтаксиса инструкции SQL/UPDATE, не так ли? - person Christian.K; 04.09.2012

У вас есть несколько маршрутов, чтобы пойти сюда:

  1. Поместите перенаправление в начале строки:

    > file echo foo
    
  2. Поместите echo в круглые скобки:

    (echo foo) > file
    

В последнем случае вы должны экранировать закрывающие скобки как ^), в первом вам может понадобиться, в зависимости от того, как выглядит окружающий код.

person Joey    schedule 05.09.2012

Экранирование конечного числа.

echo ,^1> C:\Somefile.sql
person Ansgar Wiechers    schedule 04.09.2012
comment
Перефразируя мой ответ: это единственное решение вашей проблемы. - person Ansgar Wiechers; 04.09.2012
comment
+1, я понятия не имел, что вы можете избежать 1, чтобы он не рассматривался как дескриптор файла. Довольно круто. Но это не единственное решение. Вы также можете получить правильный вывод без завершающего пробела, поместив перенаправление впереди: >c:\somefile.sql echo ,1. - person dbenham; 04.09.2012

Вы можете вывести литеральную строку. Любые и все аргументы для эха перенаправляются. Проблема в том, что у вас нет пробела между вашей строкой и перенаправлением. 1> и 1>> являются специальными версиями > (конвейерный вывод в файл, замена, если он существует) и >> (конвейерный вывод и добавление в файл, создание его, если он не существует). Они перенаправляют стандартный вывод (stdout в C++, Console.Out в C#). 2> и 2>> перенаправляют стандартный вывод ошибок (stderr в C++, Console.Error в C#).

Например:

echo 111 > a.txt
echo 111 1> a.txt

эквивалентны.

person akton    schedule 04.09.2012
comment
Проблема в том, что он пишет 111[space] в файл - person Danny Beckett; 04.09.2012
comment
Есть ли особая причина, по которой вы используете эхо? Вы можете просто сделать copy con somefilel.sql, затем ввести свой SQL и закончить его символом Control-Z/F6 (конец файла). Хотя последняя часть может быть сложнее. - person akton; 04.09.2012
comment
Это потрясающе! Никаких побегов не требуется!! Я почти уверен, что могу просто сделать CHAR(26), чтобы получить EOF. Большое спасибо @akton - я отмечу это как принятый ответ, как только проверю EOF. - person Danny Beckett; 04.09.2012
comment
К сожалению, после преобразования всех echo в моей процедуре в INSERT INTO #Temp и попытки copy con я не смог найти способ отразить CR/LF или EOF. Я попробовал коды ASCII 10, 13, 10 и 13 для CR/LF и 4, 26 и, возможно, еще пару для EOF/EOT... ничего не сработало! :( - person Danny Beckett; 04.09.2012
comment
@DannyBeckett Не могли бы вы изменить свой вопрос, включив в него содержимое нашего скрипта xp_cmdshell, пожалуйста? - person akton; 05.09.2012
comment
Готово - он просто выполняется, выполняется и выполняется (т.е. все еще ожидает ввода) @akton - person Danny Beckett; 05.09.2012
comment
@DannyBeckett Давайте сделаем шаг назад на секунду. Почему мы записываем SQL в файл? Если вы просто хотите отслеживать вывод, почему бы не записать его в журнал: stackoverflow.com/questions/123781/? - person akton; 05.09.2012
comment
Процедура заключается в резервном копировании всех процедур, функций и триггеров в указанной схеме, которые соответствуют указанному шаблону. - person Danny Beckett; 05.09.2012
comment
Почему бы не экспортировать всю схему (см. forums.asp.net/t/1667081.aspx/ 1 для примера), затем отфильтровать это? Похоже, вы делаете что-то сложно. Для него также есть сценарий powershell по адресу sqlwebpedia.com/content. /. xp_cmdshell также представляет серьезную угрозу безопасности и отключается большинством администраторов баз данных. - person akton; 05.09.2012
comment
Схема огромна - несколько гигов данных. Это экспорт процедур из среды разработки в среду заказчика. Он автоматически добавляет WITH ENCRYPTION в нужные места и т. д. Все данные, сгенерированные процедурой, выполняются за ‹ 1 секунды. Процедура запускается от имени администратора баз данных, поэтому нет риска отключения xp_cmdshell. - person Danny Beckett; 05.09.2012
comment
Как насчет использования sp_helptext (msdn.microsoft.com/en-us/library/ms176112 .aspx) для вывода текста каждой процедуры? - person akton; 05.09.2012
comment
sp_helptext ограничен 255 символами в строке. Кроме того, он использует устаревшие системные таблицы. Мое решение принимает определение напрямую: SELECT definition FROM sys.sql_modules WHERE object_id = OBJECT_ID('someschema.someproc'). Однако при любом решении copy con по-прежнему не работает. - person Danny Beckett; 05.09.2012
comment
Есть ли причина, по которой это должно работать как хранимая процедура? Можете ли вы написать короткое приложение, которое подключается к SQL, выполняет указанный выше запрос и записывает процедуры в файлы? - person akton; 05.09.2012
comment
Я согласен, что это лучшее решение. К сожалению, это тот случай, когда клиент всегда прав. Если бы я мог просто заставить работать перевод строки/конец файла, это было бы идеально с copy con - person Danny Beckett; 05.09.2012
comment
@DannyBeckett Ну, у меня была хорошая грязь вокруг себя, и я не могу заставить ее работать. Я предположил, что символ control-Z сам по себе не является символом EOF, но интерпретируется cmd.exe для завершения файла, и это кажется правильным. Самое близкое, что я мог получить, это sqlteam.com/forums/topic.asp?TOPIC_ID= 132685, но это не сработало. Я бы посмотрел на решение Джоуи. - person akton; 05.09.2012
comment
Спасибо за вашу помощь @akton - это очень ценно! :) - person Danny Beckett; 05.09.2012