我正在使用带有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
event_id是唯一的事件,这只有在我知道确切的ID时才会起作用,我无法为每个ID运行它。
有没有办法为没有游标的每个单独的event_id执行此操作。我已经看到了使用UDF的可能解决方案,遗憾的是我的第二个问题是时间表系统(CELCAT)为每年创建一个新数据库(我知道不要问)所以我将不得不使SQL动态即接下来的几年数据库将是celcat200910,我相信动态SQL无法在UDF中运行。
请记住这是SQL Server 2000
答案 0 :(得分: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
答案 1 :(得分:0)
您可以创建一个UDF来计算字符串,然后使用它:
select event_id, dbo.GetTutorsText(@eventId)
from EventsTable
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
答案 2 :(得分:0)
对于第二个问题,请使用VIEW。为celcat数据库中的每个感兴趣的表创建一个视图,并改为使用视图。
当数据库进展到下一年时,只需更新所有视图以指向新数据库。使用VIEW的系统中的每个查询现在都将寻址正确的数据库。
答案 3 :(得分: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
确保将足够的Max()表达式放入每个事件中,以覆盖尽可能多的人员。
要获取有关该事件的更多数据,请不要将其放在临时表中(这会使其变慢)。只需将此大查询用作自己的派生表,然后再连接到所需的表。
答案 4 :(得分:0)
过去几个月我做了一些软体开发 - 这有点像噩梦,我很同情你!
老实说,在这种情况下,您可能会更好地使用Celcat API(这需要一些习惯,但功能非常强大,并且具有以下优势:您的查询应该在各版本之间相当安全。)
我创建了一个类,我用它来选择特定的数据库版本等,创建一个特定于我想要使用的学年的会话。
在API中,如果需要,还可以选择直接运行SQL。
我知道这不能回答你的问题,但我希望它能解决你的问题!