var db *sql.DB // Initialize variable db in function init
func main() {
defer db.Close()
/**
oracle schema:
1:create or replace type String_ary is table of nvarchar2(2000)
2:create or replace procedure p_go_ary_test(v_ary string_ary) is
begin
null; -- Any specific logic
end;
*/
var data_ary = []string{
"a", "b", "c",
}
var err error
if true {
_, err = db.ExecContext(context.Background(), `BEGIN p_go_ary_test(:1); END;`, godror.PlSQLArrays, data_ary)
} else {
_, err = db.ExecContext(context.Background(), `BEGIN p_go_ary_test(:1); END;`, data_ary)
}
if err != nil {
/**
All calls above reported errors, as follows:
ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'P_GO_ARY_TEST'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
TODO My question is :
TODO How to successfully pass array types when calling stored procedures with godror.
*/
fmt.Println(err.Error())
} else {
fmt.Println("successfully !")
}
}
该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:
在调用存储过程时传递数组类型参数,您可以使用 godror.PlSQLArrays
常量来指示参数的类型为 PL/SQL 数组(嵌套表)。以下是一个示例代码:
import "gopkg.in/goracle.v2"
// ...
var data_ary = []string{
"a", "b", "c",
}
var arg godror.PlSQLArrays
arg.Append(data_ary)
_, err = db.ExecContext(context.Background(), `BEGIN p_go_ary_test(:1); END;`, arg)
if err != nil {
fmt.Println(err.Error())
} else {
fmt.Println("successfully !")
}
在这个示例中,我们使用 godror.PlSQLArrays
常量来指示参数类型为 PL/SQL 数组(嵌套表)。然后,我们将数组参数添加到 godror.PlSQLArrays
对象中,并将该对象作为参数传递给 db.ExecContext()
方法。
请注意,您需要使用 goracle.v2
包中的 godror.PlSQLArrays
类型和常量,而不是 database/sql
包中的类型和常量。另外,如果您使用的是 Oracle 12c 或更高版本,则需要在启动时设置 orahome
环境变量,以便 godror 能够加载正确的 Oracle 客户端库。
希望这个解决方案可以帮助您成功地传递数组类型参数给存储过程。
如果以上回答对您有所帮助,点击一下采纳该答案~谢谢
用户线程与内核线程KSE是多对一(N : 1)的映射模型,多个用户线程的一般从属于单个进程并且多线程的调度是由用户自己的线程库来完成,线程的创建、销毁以及多线程之间的协调等操作都是由用户自己的线程库来负责而无须借助系统调用来实现。一个进程中所有创建的线程都只和同一个KSE在运行时动态绑定,也就是说,操作系统只知道用户进程而对其中的线程是无感知的,内核的所有调度都是基于用户进程。许多语言实现的 协程库 基本上都属于这种方式(比如python的gevent)。由于线程调度是在用户层面完成的,也就是相较于内核调度不需要让CPU在用户态和内核态之间切换,这种实现方式相比内核级线程可以做的很轻量级,对系统资源的消耗会小很多,因此可以创建的线程数量与上下文切换所花费的代价也会小得多。但该模型有个原罪:并不能做到真正意义上的并发,假设在某个用户进程上的某个用户线程因为一个阻塞调用(比如I/O阻塞)而被CPU给中断(抢占式调度)了,那么该进程内的所有线程都被阻塞(因为单个用户进程内的线程自调度是没有CPU时钟中断的,从而没有轮转调度),整个进程被挂起。即便是多CPU的机器,也无济于事,因为在用户级线程模型下,一个CPU关联运行的是整个用户进程,进程内的子线程绑定到CPU执行是由用户进程调度的,内部线程对CPU是不可见的,此时可以理解为CPU的调度单位是用户进程。所以很多的协程库会把自己一些阻塞的操作重新封装为完全的非阻塞形式,然后在以前要阻塞的点上,主动让出自己,并通过某种方式通知或唤醒其他待执行的用户线程在该KSE上运行,从而避免了内核调度器由于KSE阻塞而做上下文切换,这样整个进程也不会被阻塞了。