我想将第一个表 InputStrings 中的值与Sql中第二个表 StringConstraints 中的值进行比较。
InputStrings
sqlobject
StringConstraints
+-----------+------------+-----------+
| Name | Address | City |
+-----------+------------+-----------+
| abcabcabc | xyxyxyxy | qweqweqwe |
| abbcabc | xyxxyxy | qweqwe |
| abccabc | xyxyxyxyxy | qwweqwe |
+-----------+------------+-----------+
我想检查 Name 列中值的长度是否在2到20之间; 地址列中的值长度介于4和10之间; City 列中的值和长度介于5和10之间。
我的表中有68行。 InputString中有40列。我无法为每一行写作。
任何人都可以帮我制作一个通用的解决方案来比较这些值吗?
我是数据库领域的新手。
答案 0 :(得分:0)
这将返回不良记录:
Select *
from InputStrings
where (len(Name) not between (select minlength from StringContraints where colName = 'Name')
and
(select maxlength from StringContraints where colName = 'Name'))
or
(len(Address) not between (select minlength from StringContraints where colName = 'Address')
and
(select maxlength from StringContraints where colName = 'Address'))
or
(len(City) not between (select minlength from StringContraints where colName = 'City')
and
(select maxlength from StringContraints where colName = 'City'))
答案 1 :(得分:0)
这是一种动态创建相同内容的方法。请记住,Stack Overflow不是编码服务。
declare @sql varchar(max) =''
,@Name varchar(50)
,@min int
,@max int
,@counter int =1;
declare csr cursor
for
select colName, minlength, [maxlength] from (values ('Name',2,20),('Address',4,10),('City',5,10)) a(colName,minlength,[maxlength])
open csr
fetch next from csr
into @Name,@min,@max
set @sql = 'select * from inputstrings where '
while @@FETCH_STATUS = 0
begin
if(@counter =1 ) set @sql = @sql + '(len('+ @name+') not between ' + cast(@min as varchar(5)) + ' and ' + cast(@max as varchar(5)) + ') '
else set @sql = @sql + 'or (len('+ @name+') not between ' + cast(@min as varchar(5)) + ' and ' + cast(@max as varchar(5)) + ') '
set @counter=@counter +1
fetch next from csr
into @Name,@min,@max
end
close csr
deallocate csr
print @sql
exec(@sql)
答案 2 :(得分:0)
你没有说明你的DMBS,所以这是Postgres的解决方案:
select *
from (
select i.id,
t.*,
c.minlength,
c.maxlength,
length(t.value) between c.minlength and c.maxlength as is_valid
from inputstrings i
cross join lateral jsonb_each_text(to_jsonb(i) - 'id') as t(colname, value)
join stringconstraints c on lower(c.colname) = lower(t.colname)
) t
where not is_valid
order by id;
这首先将表inputstrings
中的每一行转换为键/值对,并将其结果连接到stringconstraints
表。从那里可以很容易地根据约束验证列值。这与inputstrings
中的列数无关。结果将是每列一行违反约束。
对于以下设置:
create table inputstrings (id integer, name text, address text, city text);
insert into inputstrings
values
(1, 'Name OK','Some Address that is too long','City Name OK'),
(2, 'N', 'Address OK', 'Cty'),
(3, 'Good Name', 'Good Address', 'Good City');
create table stringconstraints (colname text, minlength int, maxlength int);
insert into stringconstraints
values
('Name', 2, 20),
('Address', 4, 12),
('City', 5, 15);
查询返回此结果:
id | colname | value | minlength | maxlength | is_valid
---+---------+-------------------------------+-----------+-----------+---------
1 | address | Some Address that is too long | 4 | 12 | false
2 | name | N | 2 | 20 | false
2 | city | Cty | 5 | 15 | false
我添加了id
列,以便可以将无效的列值与实际的源行匹配。
在线示例:http://rextester.com/VVG55773
包含更多列的第二个示例:http://rextester.com/QCKG53573(请注意查询未更改)