SQL Server 2000
背景
我有一张表,可以在我的课程表中存储有关特定课程的各种元数据。该表定义为:
create table course_prefs {
id int identity not null,
crs_nbr int references course (crs_nbr) not null,
fiscal_yr int not null,
group_name varchar(50) not null,
item_name varchar(50) null,
value varchar(100) not null)
并且有一些像这样的值:
ID Crs_Nbr Fiscal_Yr Group_Name Item_Name Value
1 5327 2007 StuAchievement Qualifier alg
2 5329 2007 StuAchievement Qualifier alg
153 2000 2003 LocUCInfo 543 F,0,0
154 2000 2003 LocUCInfo 542 F,0,0
6149 15746 2009 summerAttn HS coreClass
6150 12367 2009 summerAttn HS coreClass
...我已经开始从这个prefs表中查看视图以满足特定需求。但是,当我加入以下视图时:
CREATE view loc_uc_info as
select cp.crs_nbr, c.abbr, cp.fiscal_yr, convert(int,cp.item_name) as loc_id
, substring(cp.value,1,1) as subject_area
, substring(cp.value,3,1) as honors
, substring(cp.value,5,1) as can_be_elective
from course_prefs cp join course c on cp.crs_nbr = c.crs_nbr
where cp.group_name = 'LocUCInfo'
问题
我收到以下错误消息:
语法错误将varchar值'HS'转换为数据类型为smallint的列。
我想要什么
我需要在loc_id列上编写一个连接到此视图的查询。这意味着父表和视图都在作为整数键入的列上连接。但是 - 视图在item_name列中有整数和char值,因此,我得到语法错误。我该怎么做才能解决这个问题?
我尝试的事情:
答案 0 :(得分:2)
不确定你想要的结果是什么,但使用的是什么:
case when isnumeric(cp.item_name) = 1 then convert(int,cp.item_name) else null end
而不仅仅是你的
convert(int,cp.item_name)
答案 1 :(得分:1)
注意:在第一条消息下面添加了最终工作代码。
您能否在视图中详细解释您想要完成的这一行?
convert(int, cp.item_name) as loc_id,
Penfold的建议似乎很好。
这是工作代码。 (是的,它使用了2005“sys。”表。将它们转换为2000年运行。)它用Penfold的建议替换了你的“loc_id”列。
IF EXISTS (SELECT * FROM sys.tables WHERE name = 'Course')
DROP TABLE dbo.Course
GO
CREATE TABLE dbo.Course (
ID int not null, -- identity
Abbr varchar(5) not null,
Crs_Nbr int not null --references course (crs_nbr)
)
GO
IF EXISTS (SELECT * FROM sys.tables WHERE name = 'Course_Prefs')
DROP TABLE dbo.Course_Prefs
GO
CREATE TABLE dbo.Course_Prefs (
ID int not null, -- identity
Crs_Nbr int not null, --references course (crs_nbr)
Fiscal_Yr int not null,
Group_Name varchar(50) not null,
Item_Name varchar(50) null,
Value varchar(100) not null
)
GO
INSERT INTO dbo.Course VALUES (1, 'Crs1', 5327)
INSERT INTO dbo.Course VALUES (2, 'Crs2', 5329)
INSERT INTO dbo.Course VALUES (3, 'Crs3', 2000)
INSERT INTO dbo.Course VALUES (4, 'Crs4', 15746)
INSERT INTO dbo.Course VALUES (5, 'Crs5', 12367)
GO
INSERT INTO dbo.Course_Prefs VALUES (1, 5327, 2007, 'StuAchievement', 'Qualifier', 'alg')
INSERT INTO dbo.Course_Prefs VALUES (2, 5329, 2007, 'StuAchievement', 'Qualifier', 'alg')
INSERT INTO dbo.Course_Prefs VALUES (153, 2000, 2003, 'LocUCInfo', '543', 'F,0,0')
INSERT INTO dbo.Course_Prefs VALUES (154, 2000, 2003, 'LocUCInfo', '542', 'F,0,0')
INSERT INTO dbo.Course_Prefs VALUES (6149, 15746, 2009, 'summerAttn', 'HS', 'coreClass')
INSERT INTO dbo.Course_Prefs VALUES (6150, 12367, 2009, 'summerAttn', 'HS', 'coreClass')
GO
SELECT * FROM dbo.Course
SELECT * FROM dbo.Course_Prefs
GO
IF EXISTS (SELECT * FROM sys.views WHERE name = 'Loc_uc_Info')
DROP VIEW dbo.Loc_uc_Info
GO
CREATE VIEW dbo.Loc_uc_Info AS
SELECT
cp.crs_nbr,
c.abbr,
cp.fiscal_yr,
case when isnumeric(cp.item_name) = 1 then convert(int,cp.item_name) else null end AS loc_id,
--convert(int, cp.item_name) as loc_id,
substring(cp.value, 1, 1) as subject_area,
substring(cp.value, 3, 1) as honors,
substring(cp.value, 5, 1) as can_be_elective
FROM dbo.Course_Prefs AS cp
JOIN dbo.Course AS c ON cp.crs_nbr = c.crs_nbr
--WHERE cp.group_name = 'LocUCInfo'
GO
SELECT * FROM dbo.Loc_uc_Info
GO
ID Abbr Crs_Nbr
----------- ----- -----------
1 Crs1 5327
2 Crs2 5329
3 Crs3 2000
4 Crs4 15746
5 Crs5 12367
ID Crs_Nbr Fiscal_Yr Group_Name Item_Name Value
----------- ----------- ----------- -------------------------------------------------- -------------------------------------------------- ----------------------------------------------------------------------------------------------------
1 5327 2007 StuAchievement Qualifier alg
2 5329 2007 StuAchievement Qualifier alg
153 2000 2003 LocUCInfo 543 F,0,0
154 2000 2003 LocUCInfo 542 F,0,0
6149 15746 2009 summerAttn HS coreClass
6150 12367 2009 summerAttn HS coreClass
crs_nbr abbr fiscal_yr loc_id subject_area honors can_be_elective
----------- ----- ----------- ----------- ------------ ------ ---------------
5327 Crs1 2007 NULL a g
5329 Crs2 2007 NULL a g
2000 Crs3 2003 543 F 0 0
2000 Crs3 2003 542 F 0 0
15746 Crs4 2009 NULL c r C
12367 Crs5 2009 NULL c r C
编辑:忘记包含Penfold的代码。
IF EXISTS (SELECT * FROM sys.tables WHERE name = 'Course')
DROP TABLE dbo.Course
GO
CREATE TABLE dbo.Course (
ID int not null, -- identity
Abbr varchar(5) not null,
Crs_Nbr int not null --references course (crs_nbr)
)
GO
IF EXISTS (SELECT * FROM sys.tables WHERE name = 'Course_Prefs')
DROP TABLE dbo.Course_Prefs
GO
CREATE TABLE dbo.Course_Prefs (
ID int not null, -- identity
Crs_Nbr int not null, --references course (crs_nbr)
Fiscal_Yr int not null,
Group_Name varchar(50) not null,
Item_Name varchar(50) null,
Value varchar(100) not null
)
GO
INSERT INTO dbo.Course VALUES (1, 'Crs1', 5327)
INSERT INTO dbo.Course VALUES (2, 'Crs2', 5329)
INSERT INTO dbo.Course VALUES (3, 'Crs3', 2000)
INSERT INTO dbo.Course VALUES (4, 'Crs4', 15746)
INSERT INTO dbo.Course VALUES (5, 'Crs5', 12367)
GO
INSERT INTO dbo.Course_Prefs VALUES (1, 5327, 2007, 'StuAchievement', 'Qualifier', 'alg')
INSERT INTO dbo.Course_Prefs VALUES (2, 5329, 2007, 'StuAchievement', 'Qualifier', 'alg')
INSERT INTO dbo.Course_Prefs VALUES (153, 2000, 2003, 'LocUCInfo', '543', 'F,0,0')
INSERT INTO dbo.Course_Prefs VALUES (154, 2000, 2003, 'LocUCInfo', '542', 'F,0,0')
INSERT INTO dbo.Course_Prefs VALUES (6149, 15746, 2009, 'summerAttn', 'HS', 'coreClass')
INSERT INTO dbo.Course_Prefs VALUES (6150, 12367, 2009, 'summerAttn', 'HS', 'coreClass')
GO
SELECT * FROM dbo.Course
SELECT * FROM dbo.Course_Prefs
GO
IF EXISTS (SELECT * FROM sys.views WHERE name = 'Loc_uc_Info')
DROP VIEW dbo.Loc_uc_Info
GO
CREATE VIEW dbo.Loc_uc_Info AS
SELECT
cp.crs_nbr,
c.abbr,
cp.fiscal_yr,
convert(int,
case
when isnumeric(cp.item_name) = 1 then cp.item_name
else 0
end
) as loc_id,
substring(cp.value, 1, 1) as subject_area,
substring(cp.value, 3, 1) as honors,
substring(cp.value, 5, 1) as can_be_elective
FROM dbo.Course_Prefs AS cp
JOIN dbo.Course AS c ON cp.crs_nbr = c.crs_nbr
WHERE cp.group_name = 'LocUCInfo'
GO
SELECT * FROM dbo.Loc_uc_Info
GO
答案 2 :(得分:1)
试试这个:
convert(int,case when isnumeric(cp.item_name)= 1 then cp.item_name else null end as loc_id
如果不起作用,请尝试:
convert(int,case when isnumeric(cp.item_name)= 1 then cp.item_name else 0 end as loc_id
我个人认为你的基本设计存在很多缺陷,你不应该在同一列中有数字和字符数据。你也不应该用逗号分隔值。
我不是观点的粉丝,尤其是那些被置于观点之上的观点,因为当它们无法正确编入索引时会破坏性能。
答案 3 :(得分:0)
从头到尾:创建两个视图怎么样?
在没有转换的情况下执行连接,在第一个视图上执行转换的另一个。
由于第一个视图只应包含Item_Name中的数字(即543和542),因此不会出现转换错误。