我有一个以下存储过程,我重复类似的代码。我所做的就是根据Sample id1,sampleid2和sample id3检查条件,以类似的方式进行。 'y'的值一直持续到大约10,所以这将是一个很大的'if'条件的陈述。我试图看看是否可以采用更好的解决方案。感谢。
@select = 'select * from tbl Sample......'
if(x = 1 and y=1)
set @where = 'where Sample.id1 >=1 and <=10'
if(x = 1 and y=2)
set @where = 'where Sample.id1 >=11 and <=20'
if(x=2 and y=1)
set @where = 'where Sample.id2 >=1 and <= 10'
if(x=2 and y=2)
set @where = 'where Sample.id2 >=11 and <=20'
if(x=3 and y=1)
set @where = 'where Sample.id3 >=1 and <=10'
if(x=3 and y=2)
set @where = 'where Sample.id3 >=11 and <=20' //increment goes on
exec(@select+@where)
答案 0 :(得分:3)
一般情况下,如果JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi");
JMXConnector connector = JMXConnectorFactory.connect(url, null);
connector.connect();
connection = connector.getMBeanServerConnection();
ObjectName name = new ObjectName(getObjectNameByBrokerName(brokerName));
brokerMBean = (BrokerViewMBean) MBeanServerInvocationHandler.newProxyInstance(connection, name, BrokerViewMBean.class, true);
ObjectName[] objNames = brokerMBean.getQueues();
for (ObjectName objName : objNames) {
QueueViewMBean queueMBean = (QueueViewMBean) MBeanServerInvocationHandler.newProxyInstance(connection, objName, QueueViewMBean.class, true);
System.out.println(queueMBean.getName());
}
和筛选列x, y
等的值之间没有简单的关联,那么您可以将where谓词移动到由x和y值键入的表中,然后将其用作查找以应用于您的PROC。假设id1, id2
被大量使用,查找表可以永久化并在SPROC
输入映射列上建立索引。
x,y
然后你的过程简化为:
CREATE TABLE dbo.WhereMappings
(
x INT,
y INT,
Predicate NVARCHAR(MAX),
CONSTRAINT PK_MyWhereMappings PRIMARY KEY(x, y)
)
INSERT INTO dbo.WhereMappings(x, y, Predicate) VALUES
(1, 1, 'Sample.id1 > 5 and Sample.id2 <= 10'),
(1, 2, 'Sample.id1 > 7 and Sample.id2 <= 15'),
(2, 1, 'Sample.id2 > 2 and Sample.id3 <= 18');
Re:这解决了什么
虽然这不一定降低了原始查询的复杂性,但它确实允许对映射的仅数据维护方法,例如,可以编写Admin UI屏幕来维护(并验证!think Sql Injection)谓词映射,而无需直接修改SPROC。
修改强>
编辑后,CREATE PROC MyProc(@x INT, @y INT) AS
BEGIN
DECLARE @sql NVARCHAR(MAX);
DECLARE @predicate NVARCHAR(MAX);
SELECT TOP 1 @predicate = Predicate
FROM dbo.WhereMappings WHERE x = @x AND y = @y;
-- TODO THROW if predicate not mapped
SET @sql = CONCAT('SELECT * FROM Sample WHERE ', @predicate);
EXECUTE(@sql);
END;
与x, y
谓词中使用的已过滤列和范围之间存在关联,即idx
设置列,{{ 1}}设置范围。
在这种情况下,只需将x
的值附加到y
列名称存根,然后将x
子句的值乘以id
到{{ 1}};
答案 1 :(得分:1)
您可以这样做:
select
*
from
tbl Sample
where
(@x=1 and @y=1 and Sample.id1>=..and Sample.id1<=..) --(or you could use between)
OR (@x=1 and @y=2 and Sample.id1>=..and Sample.id1<=..)
..
答案 2 :(得分:1)
set @select = 'select * from tbl Sample......'
set @where = 'where Sample.id'+convert(nvarchar(10),@x)+' >=....and <=...'
exec(@select+@where)
答案 3 :(得分:0)
我建议使用另一个sql表,它将包含所有这些条件的信息,如下面的屏幕截图所示。
然后在你的SQL查询中使用join,例如。(假设上表的名称为限制
select * from tbl Sample smpl
inner join Limit lmt
on @x=lmt.x and @y=lmt.y and
(
(@x=1 and smpl.id1 >= lmt.Min_limit and smpl.id1 <=lmt.Max_limit) or
(@x=2 and smpl.id2 >= lmt.Min_limit and smpl.id2 <=lmt.Max_limit) or
(@x=3 and smpl.id3 >= lmt.Min_limit and smpl.id3 <=lmt.Max_limit)
)
在此我尝试避免动态查询。
答案 4 :(得分:0)
我经常试图找到输入和输出之间的关系,在这种情况下我发现了这种方式:
SET @where = 'WHERE Sample.id{0} >= {1} + 1 and <= {1} + 10'
SET @where = REPLACE(@where, '{0}', CAST(x AS varchar(5)))
SET @where = REPLACE(@where, '{1}', CAST((y - 1) AS varchar(5)))
答案 5 :(得分:0)
我想你想要这样的东西:
SET @where = 'where Sample.id' + CAST(@x AS VARCHAR(10)) + ' between ' +
CAST((@y - 1) * 10 + 1 AS VARCHAR(10)) + ' and ' +
CAST(@y * 10 AS VARCHAR(10))