如何获得价值比多列值,而不是使用从SQL Server复合键字段
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何获得价值比多列值,而不是使用从SQL Server复合键字段相关的知识,希望对你有一定的参考价值。
如果我有表包含以下数据:
分支,类型,数量=>这将产生复合密钥串“关键字段”
分支的长度,类型为[INT] [4] 号的长度为[INT] [7]
数据是这样的:
branch, type, number
13, 1309, 1 row1
13, 1309, 2 row2
13, 1310, 1 row3
14, 1309, 1 row4
所以我关键字段 - >称为“关键字段”列,但idont需要使用它,它的工作原理,但我只是需要使用表达式,而不是字符串关键字段,例如: 如果我需要得到该行除上述2行更大:我写道:
SELECT TOP 1 * FROM TABLE WHERE KeyField > '0013130900002'
- >我不喜欢使用字符串组合键..
我也不能手动使它像这样:
SELECT TOP 1 * FROM TABLE WHERE brn > 1 AND type > 1309 and num > 2
它不会工作...所以我只是需要获得通过表达下一行
例如:getGreatRow(1,1309,2); //这将返回ROW3什么我需要做的。所以,这个功能可直接与C#和在屏幕上的文本框使用!我需要选择只有顶部1结果比我指定当前记录或表达的值。
编辑
我用戈登SQL生成一个C#与我想要的主键的列表。由于戈登。
在C#中,使SQL查询自动生成的:
public List<EntryTable> Tables { get; private set; }
public List<BufferElement> Buffer { get; private set; }
string Query = string.Empty;
for (int i = 0; i < Tables[0].PrimaryKeys.Count; i++)
{
Query += "(";
for (int j = 0; j < i; j++)
{
switch (Tables[0].PrimaryKeys[j].CLRType)
{
case CLRType.CLR_BYTE:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = {Convert.ToByte(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)} AND ";
break;
case CLRType.CLR_INT16:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = {Convert.ToInt16(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)} AND ";
break;
case CLRType.CLR_INT32:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = {Convert.ToInt32(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)} AND ";
break;
case CLRType.CLR_INT64:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = {Convert.ToInt64(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)} AND ";
break;
case CLRType.CLR_SINGLE:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = {Convert.ToSingle(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)} AND ";
break;
case CLRType.CLR_DOUBLE:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = {Convert.ToDouble(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)} AND ";
break;
case CLRType.CLR_DECIMAL:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = {Convert.ToDecimal(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)} AND ";
break;
case CLRType.CLR_Boolean:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = {Convert.ToBoolean(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)} AND ";
break;
case CLRType.CLR_STRING:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = '{Convert.ToString(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)}' AND ";
break;
case CLRType.CLR_DATETIME:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = '{Convert.ToDateTime(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)}' AND ";
break;
case CLRType.CLR_TIME:
Query += $"{Tables[0].PrimaryKeys[j].KeyPart} = '{TimeSpan.Parse(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[j].KeyPart).Value)}' AND ";
break;
}
}
switch (Tables[0].PrimaryKeys[i].CLRType)
{
case CLRType.CLR_BYTE:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > {Convert.ToByte(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}";
break;
case CLRType.CLR_INT16:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > {Convert.ToInt16(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}";
break;
case CLRType.CLR_INT32:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > {Convert.ToInt32(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}";
break;
case CLRType.CLR_INT64:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > {Convert.ToInt64(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}";
break;
case CLRType.CLR_SINGLE:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > {Convert.ToSingle(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}";
break;
case CLRType.CLR_DOUBLE:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > {Convert.ToDouble(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}";
break;
case CLRType.CLR_DECIMAL:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > {Convert.ToDecimal(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}";
break;
case CLRType.CLR_Boolean:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > {Convert.ToBoolean(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}";
break;
case CLRType.CLR_STRING:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > '{Convert.ToString(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}'";
break;
case CLRType.CLR_DATETIME:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > '{Convert.ToDateTime(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}'";
break;
case CLRType.CLR_TIME:
Query += $"{Tables[0].PrimaryKeys[i].KeyPart} > '{TimeSpan.Parse(Buffer.Find(x => x.ID == Tables[0].PrimaryKeys[i].KeyPart).Value)}'";
break;
}
Query += $") {(Tables[0].PrimaryKeys.Count > 1 && i != Tables[0].PrimaryKeys.Count - 1 ? " OR " : string.Empty)}
";
}
Query += $"ORDER BY {string.Join(" ASC, ", Tables[0].PrimaryKeys.Select(x => x.KeyPart).ToArray())} ASC";
SelectCommand = $"SELECT TOP 1 * FROM {Tables[0].Table} WHERE " + Query;
如果您想获得1, 1309, 2
后的下一行
SELECT TOP 1 *
FROM TABLE
WHERE brn > 1 OR
(brn = 1 AND type > 1309) OR
(brn = 1 AND type = 1309 AND num > 2)
ORDER BY brn DESC, type DESC, num DESC;
我建议你涂用“数学”:把你列在“相关的订单,然后乘以适应在一个字段中的所有数字。例如:new_id=first_column*100000+second_column*10+third_column
所以在第1行的情况下,你将有1313091的代码。数学是不是字符串操作由远快。然后,您将能够查询除以你所需要的部分关键。最终加入一些更零的列你认为会增长多少。
当你为了你需要外建立与列键的顺序被保留。
所以您的查询就会像:
select *
from table
where new_id > (branch)*100000+(type)*10+number
我们的想法是这样的:
123456 99349199 12341234 : having enough space for a 'reasonable' amount of numbers
000000 00000000 00000000
so 123456 x 1 00000000 00000000 = 123456 00000000 00000000 +
99349199 x 1 00000000 = 99349199 00000000 +
and
12341234 x 1 = 12341234 =
-------------------------
123456 99349199 12341234
更新:
select *
from my_table
WHERE new_id (branch)*1 00000000 00000000+(type)*1 00000000+number
显然我们的“新标签”的定义更改:
new_label= (branch)*100000000 00000000+(type)*100000000 + number
这样你就可以拥有这些最大长度:
<all digits you want> (branch) + 8 digit (type) + 8 digit (number)
我建议你添加你的数据库触发器来强制实现这些最大长度
在数据库中创建这个功能
CREATE FUNCTION dbo.GetCompositeKey(@branch int, @type int, @number int)
RETURNS bigint
AS
BEGIN
RETURN cast(@branch as bigint) * 100000000000 + cast(@type as bigint) * 10000000 + @number
END
然后在您的比较使用它,就像这样:
SELECT TOP 1 * FROM [TABLE]
WHERE dbo.GetCompositeKey(branch, type, number) >
dbo.GetCompositeKey(13, 1309, 2)
ORDER BY dbo.GetCompositeKey(branch, type, number)
注意:此查询被简化为例证。当从C#执行它,你应该使用参数化查询提供3个整数到SQL功能,避免SQL注入攻击。
编辑:发布此之后,我在其他答案一些评论看,你说你不懂数学。在大多数至今的答案,这种方法是简单地创建一个大的整数结合你的价值的所有3个(分支,类型和数量)来创建一个相当的价值。事实上,这是你没有使用字符串连接在你的问题基于字符串的复合键同样的事情(“0013130900002”)。作为另一个答案中指出,数学方法应该会更快。在字符串中的另一个错误是零填充@number场只有5位数字,当你已经指出,它必须能够容纳7位数字。
此致,所有的答案至今使用基本的数学运算。你将不能够走得很远,作为一个程序员,如果你不理解基本的数学,所以你应该让以提高该技能的优先事项。
你已经在你不想填充DataSet或使用MoveNext的其他的答案,等评论说,另一种方法是创建一个包含复合键的视图。
首先,创建我my other answer定义的函数
然后,创建视图
CREATE VIEW [myview]
AS
SELECT
*,
dbo.GetCompositeKey(branch, type, number) as CompositeKey
FROM [table]
查询这样的:
SELECT TOP 1 * FROM [myview]
WHERE CompositeKey > dbo.GetCompositeKey(13, 1309, 2)
ORDER BY CompositeKey
这种方法可能改善对我的其他答案的查询性能。你需要测试它找出来。
以上是关于如何获得价值比多列值,而不是使用从SQL Server复合键字段的主要内容,如果未能解决你的问题,请参考以下文章