將每個行專案從 SQL Server 資料庫匯出到它自己的 XML 檔案時遇到問題。
我在現場閱讀的所有問題都有各種知識點,這些知識點不能為我解決答案,而且我在知識上有一兩個尖銳的差距讓我失望。基本上對于每個專案(一個名為 BPAProcess 的表中的約 350 行存在于 6 個資料庫中,每個資料庫基本上是一個不同的版本,它們彼此獨立。所以理想情況下,我可以在每個資料庫上手動執行此查詢 6 次一次以提取此表中的所有行)我想為每一行獲取 XML 并將其保存在本地,單元格的 xml 內容已經適合他們只需要匯出的 xml 結構。到目前為止,我已經嘗試創建一個回圈機制來回圈我創建的臨時表,然后為每個行專案將其提取到 SQL 命令中以保存詳細資訊。我已經走到了 BCP 失敗的地步,因為它可以'
USE [BP6.8.1]
GO
-- Save XML records to a file:
DECLARE @fileName VARCHAR(175)
DECLARE @filePath VARCHAR(175)
DECLARE @sqlStr VARCHAR(1000)
DECLARE @sqlCmd VARCHAR(1000)
DECLARE @MaxRowsCount INT
DECLARE @Iter INT
select ROW_NUMBER() OVER (order by processid) row_num, name, processxml into #Process from BPAProcess
SET @MaxRowsCount = (SELECT MAX(row_num) FROM #Process)
SET @Iter = 1
WHILE @Iter <= @MaxRowsCount
BEGIN
SET @fileName = (select name from #Process where row_num = @Iter)
SET @filePath = 'C:\Temp\sql queries\' @fileName '.xml'
SET @sqlStr = 'select processxml from #Process where row_num =' cast(@Iter as varchar(3))
SET @sqlCmd = 'bcp "' @sqlStr '" queryout "' @filePath '" -w -T'
--EXEC xp_cmdshell @sqlCmd
SET @Iter = @Iter 19090
-- 19090 just to execute first iteration only
END
Drop TABLE #Process
我覺得我需要的是某種方式來回圈 #Process 表和 row_num 中的每個專案,然后通過 stdout/similar 將其匯出,或者創建一個回圈機制來執行 bpc 命令,sql 指向我想要的 xml 單元格但是我不知道如何讓 bpc 看到我正在創建的表。
很少有警告,這不是我的資料庫,它是應用程式使用的資料庫,更改任何內容都不是一種選擇。任務是獲取每個單獨的 XML 并將其存盤在保存為 [name].xml 的檔案驅動器上,其中 name 在表中。我知道這不是(從到處閱讀評論)使用 SQL 的正確方法,不可否認,我不是 SQL 開發人員,我們也沒有手,但我的任務是匯出此代碼,GUI 上的手動方式將采用幾個星期,因為這是一個漫長而費力的程序,而這會快得多。XML 內容很長,就像我在某些情況下所說的 300k->500k。
任何幫助表示贊賞,如果該幫助是“這不適合執行 SQL”,我可以在 C# 或其他一些語言中探索它,如果這真的不是它應該完成的方式。
uj5u.com熱心網友回復:
當你說某人粗魯時,你應該期待一個實際的答復嗎?具有任何重要經驗的開發人員(您)應該能夠找到可能的解決方案并評估其可用性。例如,搜索“sql server export one row to file”會使用游標找到第一個條目。
坦率地說,您似乎在不同語言方面擁有豐富的經驗,所以我質疑您為什么選擇基于 TSQL 的解決方案,而不是涉及您擅長的任何語言的解決方案。但這是一個非常不同的問題。不管 - 無論語言/開發平臺如何,RBAR 仍然是 RBAR。
轉換為簡單游標的代碼如下。有些事情是你假設的,我再次建議你使用你精通的語言。
declare @sql varchar(500);
declare @name varchar(20);
declare c1 cursor FAST_FORWARD for
select name from dbo.mytable order by name;
open c1;
fetch next from c1 into @name;
while @@fetch_status = 0
begin
--print @name;
set @sql = 'select processxml from dbo.mytable where name = ''' @name '''';
set @sql = 'bcp "' @sql '" queryout "' 'C:\Temp\sql queries\' @name '.xml " -w T'
print @sql;
fetch next from c1 into @name;
end;
close c1;
deallocate c1;
您可能需要對此進行調整以使用特定登錄名連接到正確的實體和資料庫。該檔案有游標示例 - 始終是一個很好的起點。也許您應該嘗試的第一件事是從命令提示符使用 BCP 將單個特定行中的該列匯出到特定檔案,以首先驗證您的假設和期望。
只需做一點作業,您就可以添加一些額外的邏輯來為給定實體中的多個資料庫運行它。這樣做需要處理生成的檔案集中的名稱沖突。
最后,您的代碼原樣,但不依賴帶有 BCP 命令的臨時表。請注意由于小提琴中的簡化表格而進行的小調整。
--select ROW_NUMBER() OVER (order by processid) row_num, name, processxml
select ROW_NUMBER() OVER (order by name) row_num, name
into #Process
from dbo.mytable
SET @MaxRowsCount = (SELECT MAX(row_num) FROM #Process)
SET @Iter = 1
WHILE @Iter <= @MaxRowsCount
BEGIN
SET @fileName = (select name from #Process where row_num = @Iter)
SET @filePath = 'C:\Temp\sql queries\' @fileName '.xml'
SET @sqlStr = 'select processxml from dbo.mytable where row_num =' cast(@Iter as varchar(3))
SET @sqlCmd = 'bcp "' @sqlStr '" queryout "' @filePath '" -w -T'
print @sqlCmd;
--EXEC xp_cmdshell @sqlCmd
SET @Iter = @Iter 1
END
Drop TABLE #Process
小提琴來證明兩者。
uj5u.com熱心網友回復:
這真的不是 T-SQL 的作業,它不是一種通用的腳本語言,它僅用于查詢。
相反,使用 Powershell 將 XML 提取為單獨的行,然后將它們輸出到檔案中
Invoke-Sqlcmd
-ServerInstance "YourServer"
-Database "YourDB" -Username "user" -Password "pass"
-Query "select name, processxml from dbo.mytable;"
| % {
Out-File -FilePath ("Downloads\temp\" $_.name ".xml") -InputObject $_.processxml
}
您還可以使用任何其他客戶端應用程式來執行相同的操作,這比在 T-SQL 中要容易得多。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/365398.html
標籤:sql sql-server xml
