Oracle 参数:需要固定字符长度的填充值

Oracle Parameters: expects padded value for fixed char length

提问人:Marc Wittmann 提问时间:6/26/2023 更新时间:6/26/2023 访问量:71

问:

当您有一个固定长度的字符列并且不知道列有多大时,如何有效地使用 OracleCommand 和 Parameters 从 Oracle DB 获取数据?

假设我们想要获取一个名为 IID 的 ID,该 ID 是固定的字符(5 个字节)。

 OracleCommand myCommand1;
 myCommand1.CommandText = "SELECT * FROM IDS WHERE IID = :IID";
 myCommand1.Parameters.AddWithValue("IID", "1234");

不会退回物品,但

 myCommand1.Parameters.AddWithValue("IID", "1234 ");

会,因为它与数据库中的 5 个字节匹配

您还可以指定空格

myCommand1.Parameters.Add("IID", OracleDbType.Char, 5).Value = "1234";

但就我而言,假装程序员并不总是知道数据库中定义的字符大小的确切数量(如果它有意义与否)。我使用 devart,但我认为这更像是一个普遍问题。如何在没有填充的情况下传递“1234”参数?

提前致谢

C# Oracle Devart 命名参数

评论

0赞 jdweng 6/26/2023
你永远不应该垫子。如果填充,则在获取数据时必须删除填充。
0赞 Ralf 6/26/2023
如果它不是固定长度的,为什么它是固定长度的列?而且你不应该允许任何人针对未知/未定义/未记录的模型编写不受监督的 sql。
0赞 Marc Wittmann 6/26/2023
是的,没错,反正我不想垫。这大约是关于一个旧应用程序的一万行代码,它连接到一个(记录的)数据库,现在出于安全原因使用命名参数。一切正常,尽管使用确切的定义会更好,但没有人会为应用程序的额外工作付费,除了更好地记录连接代码之外,没有其他好处。我宁愿以不同的方式做。

答:

1赞 MT0 6/26/2023 #1

“数据类型比较规则”文档中:

空白填充和非填充比较语义

使用空白填充语义时,如果两个值的长度不同,则 Oracle 首先将空格添加到较短值的末尾,使其长度相等。然后,Oracle 逐个字符地比较值,直到第一个不同的字符。在第一个不同位置具有较大字符的值被认为更大。如果两个值没有不同的字符,则认为它们相等。此规则意味着,如果两个值仅在尾随空格数上不同,则它们相等。仅当比较中的两个值都是数据类型 、 文本文本或函数返回的值的表达式时,Oracle 才使用空白填充的比较语义。CHARNCHARUSER

对于非填充语义,Oracle 会逐个字符比较两个值,直到第一个不同的字符。该位置具有较大特征的值被认为更大。如果两个不同长度的值在较短的值的末尾相同,则认为较长的值更大。如果两个长度相等的值没有不同的字符,则认为这些值相等。每当比较中的一个或两个值的数据类型为 或 时,Oracle 都会使用非填充比较语义。VARCHAR2NVARCHAR2

如果有两个值,则 Oracle 应使用空白填充比较语义,并将空格添加到字符串中,直到它们长度相等。CHAR

如果您有一个或多个值,则 Oracle 将使用非填充比较语义。VARCHAR2

这意味着您应该能够传递任何长度的 a,并且将在适当的长度进行比较:CHAR

string iid = "1234";
myCommand1.Parameters.Add("IID", OracleDbType.Char, iid.Length).Value = iid;

注意:如果您遇到此问题,则建议您不应将字符串存储为 CHAR,而应改用 VARCHAR2

评论

0赞 Marc Wittmann 6/27/2023
感谢您的详细回答,非常感谢。你是对的。一般来说,这应该有效。就我而言,我使用了问题中所述的另一个参数名称。我使用“KontoId”作为参数名称和sql占位符:KontoId(NOT值),如果我不使用填充,则不会返回任何内容。更改为“Konto”后,它起作用了。我不知道为什么。我以为可能是保留词“id”,但事实并非如此。你对此有什么见解吗,根据文档,这根本不应该发生