我有两个查找表MyProviders
和MyGroups
。在我的存储过程中,我有一个临时表(用本例中的实际表替换)和数据。一列EntityId
指提供者或组。 EntityTypeId
在临时表中告诉我实体是1 = Provider还是2 = Group。 EntityId
可以包含数字GroupId
或字母数字ExternalProviderId
。
我想检查一下我的临时表中是否有来自clientOid + entityid
和myprovider
表的mygroup
组合无效的记录。
create table MyProviders
(
id int,
clientoid varchar(20),
externalproviderid varchar(20),
name varchar(25)
)
create table MyGroups
(
id int,
clientoid varchar(20),
name varchar(25)
)
create table MyJobDetails
(
clientoid varchar(20),
entityid varchar(20),
entitytypeid int,
entityname varchar(30)
)
insert into MyJobDetails values ('M.OID', 'MONYE', 1, 'Mark')
insert into MyJobDetails values ('M.OID', 2, 1, 'Lori')
insert into MyJobDetails values ('M.OID', 2, 2, 'Group 1')
insert into MyJobDetails values ('M.OID', 44444, 2, 'Group 2')
insert into MyProviders values (1, 'M.OID', 'MONY', 'Richard')
insert into MyProviders values (2, 'M.OID', '2', 'Mike')
insert into MyProviders values (3, 'M.OID', '3', 'Lori')
insert into MyGroups values (1, 'M.OID', 'Group 1')
insert into MyGroups values (2, 'M.OID', 'Group 2')
我尝试了以下查询来确定是否存在无效实体。
select
COUNT(*)
from
MyJobDetails as jd
where
not exists (select 1
from MyProviders as p
where p.ClientOID = jd.ClientOID
and p.ExternalProviderID = CAST(jd.EntityId as varchar(20))
and jd.EntityTypeId = 1)
and not exists (select 1
from MyGroups as g
where g.ClientOID = jd.ClientOID
and g.Id = jd.EntityId
and jd.EntityTypeId = 2)
这可以正常工作,直到我在临时表中获得的字母数字数据在提供程序表中不存在。我收到以下错误消息:
转换varchar值时转换失败' MONYE'数据类型int。
我尝试更新其他线程中提到的解决方案以使用IsNumeric
,但它也没有用。在此示例中,我需要为MONYE
的一个无效条目返回1,该条目在MyProvider
或MyGroup
表格中不存在。
另外,如果我能以更好的方式优化查询以实现我想要的目标吗?
答案 0 :(得分:1)
在我看来,这是一个非常糟糕的设计。
由于您引用了两个表中的一个,因此无法强制执行参照完整性。
为您的密钥设置不同的数据类型会让事情变得更糟糕。
我会用
MyJobDetails
- 一个到MyProvider
(varchar(20)
),另一个到MyGroup
(int
)这样,两者都可以是每个引用表的正确数据类型,您不再需要EntityTypeId
列。
作为旁注:无论何时在SQL Server中使用Varchar
,无论是定义参数,变量还是在CAST
语句中使用它,我都建议始终明确定义varchar
的长度。
或者你知道转换中varchar
的长度是多少吗?
CAST(jd.EntityId as varchar)
使用明确的长度 - 始终 - 这是一个好的,安全的做法:
CAST(jd.EntityId as varchar(15))
答案 1 :(得分:0)
在第二个AND NOT EXISTS部分中,将g.Id(一个int)与jd.EntityId(一个varchar)进行比较。将g.Id转换为varchar。
and not exists (select 1
from #MyGroups as g
where g.ClientOID = jd.ClientOID
and CAST(g.Id AS VARCHAR(20)) = jd.EntityId
and jd.EntityTypeId = 2)
答案 2 :(得分:0)
试试这个
select count(*)
from (
select clientoid,entityid from #MyJobDetails where entitytypeid=1
except
select p.ClientOID ,convert(varchar(200),p.ExternalProviderID) from #MyProviders p inner join #MyJobDetails jd on p.ClientOID = jd.ClientOID and p.ExternalProviderID = CAST(jd.EntityId as varchar(20)) where jd.EntityTypeId = 1
except
select g.ClientOID,convert(varchar(200),g.Id) from #MyGroups g inner join #MyJobDetails jd on g.ClientOID = jd.ClientOID and g.Id = jd.EntityId where jd.EntityTypeId = 2
)a