У меня есть нижний скрипт T-SQL:
USE [master]
RESTORE DATABASE [WH_BEE] FROM
DISK = N'F:\NH\WH_BEE_20240819_1.bak',
DISK = N'F:\NH\WH_BEE_20240819_2.bak',
DISK = N'F:\NH\WH_BEE_20240819_3.bak',
DISK = N'F:\NH\WH_BEE_20240819_4.bak',
DISK = N'F:\NH\WH_BEE_20240819_5.bak',
DISK = N'F:\NH\WH_BEE_20240819_6.bak' WITH FILE = 1,
MOVE N'WH_Data1' TO N'F:\data\WH_BEE.MDF',
MOVE N'WH_Data2' TO N'F:\data\WH_BEE_1.NDF',
MOVE N'WH_Log' TO N'G:\log\WH_BEE.LDF', NOUNLOAD, STATS = 5
Я пытаюсь вместо указания отдельной даты, например «20240819», изменить эти части (используя подстановочный знак), чтобы она больше походила на:
DISK = N'F:\NM\WH_BEE_' + * + '_1.bak'
DISK = N'F:\NM\WH_BEE_' + * + '_2.bak'
DISK = N'F:\NM\WH_BEE_' + * + '_3.bak'
DISK = N'F:\NM\WH_BEE_' + * + '_4.bak'
DISK = N'F:\NM\WH_BEE_' + * + '_5.bak'
DISK = N'F:\NM\WH_BEE_' + * + '_6.bak'
Кроме того, если у меня может быть больше шести файлов, могу ли я сделать этот T-SQL более динамичным (вместо того, чтобы строго 6, на всякий случай, можно увеличить до 7...)?
Обновление (21.08.2024 – последний сработавший код):
@Charlieface Всегда требуется указать сегодняшнюю дату. Я предпочитаю оставаться в рамках T-SQL, а не другого языка, поскольку этот сценарий почти готов к использованию. Я пришел к этому после многих испытаний с использованием другого образца T-SQL. Спасибо.
вы не установили значение @maxInputFiles
, оно все равно равно нулю. В этом примере вы бы установили его на 6.
@Charlieface Извините. Я все еще получаю сообщение об ошибке (как показано вверху).
извините, отсутствует цитата, см. редактирование.
@Charlieface Это сработало !! На самом деле мне пришлось немного изменить способ отображения даты. Я обновил пост, указав, как я изменил ваш. Огромное спасибо за последние два-три дня! Итак, является ли максимум 6 статическим пределом?
Вы можете создать его динамически, используя STRING_AGG
с параметром, указывающим количество файлов.
В SQL 2022 и Azure вы можете просто использовать GENERATE_SERIES
для получения нескольких строк. В противном случае используйте предложение VALUES
и несколько перекрестных соединений. Есть другие варианты для создания нескольких строк из ничего.
DECLARE @sql nvarchar(max);
DECLARE @maxInputFiles BIGINT = 6;
WITH L1 AS (
SELECT *
FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n(n)
),
L2 AS (
SELECT 1 n
FROM L1 AS a, L1 AS b
)
SELECT @sql = N'
RESTORE DATABASE [WH_BEE]
FROM ' +
STRING_AGG(
CONCAT('
DISK = N''F:\NH\WH_BEE_',
CONVERT(nvarchar(10), GETDATE(), 110),
'_',
g.value,
'.bak'''
),
', '
) + N'
WITH FILE = 1,
MOVE N''WH_Data1'' TO N''F:\data\WH_BEE.MDF'',
MOVE N''WH_Data2'' TO N''F:\data\WH_BEE_1.NDF'',
MOVE N''WH_Log'' TO N''G:\log\WH_BEE.LDF'', STATS = 5;
'
FROM (
SELECT TOP(@maxInputFiles)
ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS value
FROM L2
) AS g;
PRINT @sql; -- your friend
EXEC master.sys.sp_executesql @sql;
Честно говоря, вам, вероятно, следует просто использовать Powershell и модуль DbaTools. Это позволит автоматически получить все правильные файлы и сгенерировать правильный оператор. Например
Get-ChildItem "F:\NH\WH_BEE_$(Get-Date -Format "yyyyMMdd")_*.bak" | `
Restore-DbaDatabase `
-SqlInstance instanceName `
-Database DbName `
-FileMapping @{
"WH_Data1" = "F:\data\WH_BEE.MDF";
"WH_Data2" = "F:\data\WH_BEE_1.NDF";
"WH_Log" = "G:\log\WH_BEE.LDF"
};
@Charleface Я попробовал ваш T-SQL и получил эту ошибку (обновлено в сообщении (вверху)). Кроме того, нужно ли мне сначала создать базу данных и запустить этот скрипт?
Извините, пропустил строчку. Обратите внимание, что GENERATE_SERIES
поддерживается только в SQL20222 и Azure, в противном случае мы можем изменить его на подсчет перекрестных соединений. Нет, RESTORE DATABASE
специально требует, чтобы база данных не существовала, в противном случае вам нужно использовать опцию , REPLACE
Извини. Я не уверен, как исправить ошибку. Я не уверен, как перейти на «подсчет перекрестных соединений». Я использую SQL 2019. Сообщение об ошибке размещено вверху.
Смотрите новое редактирование, извините, пропустил псевдоним
Какая именно логика вам нужна, файлы bak всегда последовательно нумеруются с 1? Вам всегда нужна сегодняшняя дата или вам нужно передать параметр? Рассматривали ли вы возможность использования Powershell и DbaTools
Restore-DbaDatabase
, которые делают большую часть этой работы за вас docs.dbatools.io/Restore-DbaDatabase.html