2009-06-25 87 views
0

我正在使用SQL Server 2000後端的時間表系統,我需要列出他們旁邊的導師和房間的事件,這可能會超過1個,因此可以將多行房間和導師轉換爲+分隔列表。我用下面的代碼在過去:來自行的連接列值

DECLARE @Tutors as varchar(8000) 

SELECT @Tutors = isnull(@Tutors + ' + ', '') + name 
FROM (
    SELECT CT_EVENT_STAFF.event_id, CT_EVENT_STAFF.weeks, 
     CT_STAFF.unique_name, CT_STAFF.name 
    FROM celcat200809.dbo.CT_EVENT_STAFF AS CT_EVENT_STAFF 
    LEFT OUTER JOIN celcat200809.dbo.CT_STAFF AS CT_STAFF 
     ON CT_EVENT_STAFF.staff_id = CT_STAFF.staff_id 
    WHERE event_id = @eventID 
) As data_set 

print @Tutors 

的事項標識是唯一的事件,這隻會工作的時候我知道確切的ID,我不能爲每一個ID運行它。

有沒有辦法做到這一點,每個單獨的event_id沒有遊標。不幸的是,我的第二個問題是時間表系統(CELCAT)爲每年創建一個新的數據庫(我知道不問),所以我將不得不使SQL動態化明年的數據庫將是celcat200910,我相信動態SQL不能在UDF中運行。

請記住這是SQL Server 2000中

+0

關於DB的安排:聽起來很粗糙。是的,UDF中不允許動態SQL。你可能會發現一些有用的幫助,在這個線程的多個數據庫工作:http://stackoverflow.com/questions/1037174/sql-use-statement-with-variable/1037961#1037961 ...但是,我認爲最好的解決方案會試圖找到某種方式將數據放在某個數據庫中 - 但這可能超出了您的權限和責任範圍。 – 2009-06-25 15:45:47

+0

我將大部分數據放入考勤數據和類似數據的獨立數據庫中。我使用隔夜過程來填充這些東西,但是這個特定查詢需要生效 – PeteT 2009-06-26 00:52:39

回答

1

您仍然可以使用goodgai建議的視圖,但不是讓它重定向到一個表,而是讓它聯合選擇表。如果尚未完成並且您需要它,可以將年/月分成列。

CREATE VIEW UNIFIED_CT_STAFF 
AS 
SELECT year = 2008, month = 9, unique_name, name FROM celcat200809.dbo.CT_STAFF 
UNION SELECT year = 2008, month = 10, unique_name, name FROM celcat200810.dbo.CT_STAFF 
0

您可以創建一個UDF來計算的字符串,然後使用它像:

if object_id('dbo.GetTutorText') is not null 
    drop function dbo.GetTutorText 
go 
create function dbo.GetTutorText(
    @eventID int) 
returns varchar(8000) 
as 
begin 
DECLARE @Tutors as varchar(8000) 

SELECT @Tutors = isnull(@Tutors + ' + ', '') + name 
FROM (
    SELECT CT_EVENT_STAFF.event_id, CT_EVENT_STAFF.weeks, 
     CT_STAFF.unique_name, CT_STAFF.name 
    FROM celcat200809.dbo.CT_EVENT_STAFF AS CT_EVENT_STAFF 
    LEFT OUTER JOIN celcat200809.dbo.CT_STAFF AS CT_STAFF 
     ON CT_EVENT_STAFF.staff_id = CT_STAFF.staff_id 
    WHERE event_id = @eventID 
) As data_set 

return @Tutors 
end 
go 

select event_id, dbo.GetTutorsText(@eventId) 
from EventsTable 

的UDF可以像定義

+0

returns varchar(4000) DECLARE @Tutors as varchar(8000) tsk。嘖。 也isnull(@Tutors +'+','') - > @Tutors +'+'永遠爲空 – Coentje 2009-06-29 16:00:44

0

對於第二個問題,使用VIEW。爲ce​​lcat數據庫中的每個感興趣的表創建一個視圖,然後使用視圖。

當數據庫進展到下一年時,只需更新所有視圖以指向新的數據庫。系統中使用VIEW的每個查詢都將處理正確的數據庫。

0
  • 我可以問一下你爲什麼需要連接在服務器上的名字?客戶端應用程序不能爲你做這件事嗎?

  • 如果您在其他數據庫中尋址表時遇到問題,請使用標準化名稱創建視圖(每個表一個),只需從每個表中選擇*即可。您可以編寫一個自動創建視圖的SP,讓您只傳入要設置所有視圖的數據庫的名稱。這些觀點不會以任何重大的方式損害業績。

  • 由於您正在使用CT_STAFF的左連接,因此我相信職員可能會丟失,在這種情況下,您的表達式會將數據連接起來而丟失數據,因爲它不允許NULL員工名稱(它會在每次遇到NULL職員名稱時重置列表)。

這裏有可能就是你所需要的查詢,但它是一個黑客位的:

SELECT 
    seqid = identity(int, 1, 1), 
    event_id, 
    S.name 
INTO #EventNames 
FROM 
    celcat200809.dbo.CT_EVENT_STAFF ES 
    LEFT JOIN celcat200809.dbo.CT_STAFF S ON ES.staff_id = S.staff_id 
ORDER BY 
    event_id, 
    S.name --optional, whatever you like here. 

SELECT 
    EN.event_id, 
    Max(CASE seqid - minseqid WHEN 0 THEN EN.name ELSE '' END)) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 1 THEN EN.name ELSE NULL END, '')) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 2 THEN EN.name ELSE NULL END, '')) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 3 THEN EN.name ELSE NULL END, '')) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 4 THEN EN.name ELSE NULL END, '')) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 5 THEN EN.name ELSE NULL END, '')) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 6 THEN EN.name ELSE NULL END, '')) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 7 THEN EN.name ELSE NULL END, '')) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 8 THEN EN.name ELSE NULL END, '')) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 9 THEN EN.name ELSE NULL END, '')) 
    + Max(Coalesce(' + ' + CASE seqid - minseqid WHEN 10 THEN EN.name ELSE NULL END, '')) 
FROM 
    #EventNames EN 
    INNER JOIN (
     SELECT event_id, minseqid = Min(seqid) FROM #EventNames GROUP BY event_id 
    ) X ON EN.event_id = X.event_id 
GROUP BY EN.event_id 

只要確保把那些最大的就夠了()的表達式中覆蓋最大每個活動可能有多少員工。

要獲取有關該事件的更多數據,請勿將其放入臨時表(這會讓它變慢)。只要使用這個大的查詢作爲它自己的派生表,並回到你需要的表。

0

在過去的幾個月中,我已經做了一些celcat開發 - 這有點噩夢,我很同情你!老實說,在這種情況下,你可能會更好地使用Celcat API(這需要一些習慣,但功能相當強大,並且具有這樣的優點,即你的查詢應該在各個版本中相當安全)。

我創建了一個類,我用它來選擇特定的數據庫版本等,創建特定於我想要使用的學年的會話。

在API中,如果需要,還可以選擇直接運行SQL。

我知道這並不回答你的問題,但我希望它能解決你的問題!