原始类型变量在 PL/SQL 代码中是不可变的吗?

Posted

技术标签:

【中文标题】原始类型变量在 PL/SQL 代码中是不可变的吗?【英文标题】:Are the RAW type variables immutable in PL/SQL code? 【发布时间】:2015-10-06 09:24:54 【问题描述】:

RAW 类型变量在 PL/SQL 代码中是不可变的吗?我的意思是我可以在不复制内存的情况下就地更改RAW 类型变量的特定字节吗?

当然,我们有 UTL_RAW 包,其中包含一些适用于规范字节更改的例程,但看起来它们都复制变量实例内存:

UTL_RAW.BIT_ANDUTL_RAW.BIT_ORUTL_RAW.OVERLAY

这个问题也与有效的字符串连接问题密切相关。例如,在 Java 中,字符串也是不可变的,我们有用于此任务的 StringBuilder。 我没有在 Oracle 文档中找到关于此的明确信息。经过一番谷歌搜索[1],答案看起来如下:是的。 RAW 类型变量在 PL/SQL 代码中是不可变的,字符串也是。 真的吗?最好对这个问题有更多的解释和历史。

参考资料:

    https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:10445025326812#followup-76860752200038

【问题讨论】:

不确定我是否理解这个问题的目的。您当然可以更新 RAW 变量,就像任何其他变量一样。语义是一样的。关于 NOCOPY 参数的例外情况也同样适用——但据我所知,这不适用于 UTL_RAW 中的任何函数。为什么需要在不复制内存的情况下更改 RAW 变量的特定位? 一般目的是清除 PL\SQL 机器的内部行为。也存在使用字符串\raw 的效率的实际问题。如果我们对它们进行大量操作,我们将获得高内存流量。例如串联。为什么这让我感到困惑?因为 Java 以及 StringBuilder 存在于其中的原因。看起来我们在 Java 中有问题和解决方案,而在 PL\SQL 中我们只有问题。 仍然不确定您的问题是什么。如果纯 PL/SQL 的性能是一个问题,那么使用 NOCOPY 和/或本机编译的 PL/SQL 可能是探索的途径。尽管如此,RAW 变量本身并不是问题。您可能正在使用它们来解决问题 - 您要解决的问题是什么? 你能建立一些测试用例吗? plsql 字符串操作有什么不好? 【参考方案1】:

在 PL/SQL 中没有改变分配给变量的内存的特定子部分这样的事情。如果它是一个函数(如上述utl_raw 例程的情况),它总是返回一个值的新实例。如果它是一个带有in out nocopy 参数的过程,它可能在reference to the argument 上工作,而不是在它的副本上,但过程中的实际工作仍然涉及复制值,而不是在相同的记忆。 (嗯,好的,这不适用于 LOB,但这不是你问的问题。)

PL/SQL 是 SQL 之上的过程语言。它旨在允许以程序方式使用 SQL,它的设计目的不是超快速、超有效。如果您需要直接在内存中更改字节,您可能需要使用 C 或汇编程序。

【讨论】:

嗨,你有 的参考吗?如果它是一个带有 in out nocopy 参数的过程,它适用于对参数的引用,而不是它的副本,但仍然是实际的过程中的工作涉及复制值,而不是在同一内存中工作。? 除了@FlorinGhita,如果它是一个函数(就像上面提到的 utl_raw 例程一样),它总是会返回一个新的实例。值 。这在没有文档参考的问题中也有说明。您的回答没有带来太多关于该主题的信息。 我不知道还能告诉你什么?有一个简单的常识告诉我,从函数返回值只涉及内存复制,就像基本的variable := variable 分配一样。 @FlorinGhita,添加了 Oracle 文档参考。

以上是关于原始类型变量在 PL/SQL 代码中是不可变的吗?的主要内容,如果未能解决你的问题,请参考以下文章

在Java中String类为什么要设计成final?String真的不可变吗?其他基本类型的包装类也是不可变的吗?

根据定义,值类型是不可变的吗?

pl/sql 字符类型

SQL记录-PLSQL数组

java中是啥是不可变对象和可变对象

Oracle PL/SQL:如何使用可变数组作为输出参数执行过程?