【问题标题】:Keeping SYSDBA connection open in C++在 C++ 中保持 SYSDBA 连接打开
【发布时间】:2023-04-18 22:35:02
【问题描述】:

问题:我正在尝试以“SYSDBA”身份连接,然后在我的 C++ 应用程序中创建一个用户。在运行 create 命令之前,与 SYSDBA 的连接似乎已关闭。

我正在尝试运行以下两个命令:

  1. CONNECT sys/<syspassword>@<datasource> AS SYSDBA
  2. CREATE USER "<username>" PROFILE "DEFAULT" IDENTIFIED BY "<userpassword>" ACCOUNT UNLOCK

如果我在 Oracle SQL Developer 中突出显示并运行这两个命令,则一切正常并创建了用户。连接自动关闭,我收到如下消息:

已连接

已创建用户“KYLE”。

CONNECT 脚本命令创建的连接断开

当我从 C++ 应用程序运行命令时,似乎在运行命令 #2 之前连接已关闭。

这是我用来调用命令的代码:

strcpy(szProcName,"CONNECT sys/");
strcat(szProcName,Sys_Password);
strcat(szProcName,"@");
strcat(szProcName,info.szServerName);
strcat(szProcName," AS SYSDBA");
rc=SQLPrepare(sqlc.g_hstmt,(SQLCHAR*)szProcName,(SQLINTEGER)strlen(szProcName));
rc = SQLExecute(sqlc.g_hstmt);
                
strcpy(szProcName,"CREATE USER \"");
strcat(szProcName,userName);
strcat(szProcName,"\" PROFILE \"DEFAULT\" IDENTIFIED BY \"");
strcat(szProcName,Password);
strcat(szProcName,"\" ACCOUNT UNLOCK;");
rc=SQLPrepare(sqlc.g_hstmt,(SQLCHAR*)szProcName,(SQLINTEGER)strlen(szProcName));
rc = SQLExecute(sqlc.g_hstmt);

在 C++ 中运行命令时,出现 SQL 错误:

SQL 错误:ORA-01031:“权限不足”

另外,如果我尝试在 Oracle SQL Developer 中一次运行一个命令,我会收到相同的消息。这使我认为我的连接提前关闭了。有没有办法让我的连接保持足够长的时间来运行CREATE USER 命令?

【问题讨论】:

  • 如果您将命令更改为诸如 Select 1 from dual 之类的无害命令会发生什么; ?
  • 我执行 SQL 命令的方式之前已经完美运行了几十次。但是,既然我必须以 SYSDBA 身份连接,就会出现问题。 select 语句可以正常工作,因为您不需要 SYSDBA 权限。谢谢。

标签: c++ sql oracle oracle11g sysdba


【解决方案1】:

我相信纯 ODBC 连接不支持 Oracle 连接字符串的“AS SYSDBA”选项。

解决方案是让他们连接到具有您需要的特定权限的用户(在您的示例中创建任何用户),“as sysdba”问题会自行解决。

【讨论】:

  • 虽然这不是我要找的答案(看看我的解决方案),但我不想浪费声誉。您确实提供了一种可能的解决方案,谢谢。
【解决方案2】:

您可以使用一个具有 dba 权限的伪用户,并从您的脚本连接到该用户。由于新用户还将拥有管理员权限,您将能够创建其他用户或您希望完成的任何其他任务。

create user test identified by password ;
grant dba to test with admin option;

现在使用您的脚本连接到“测试”并执行您的操作。

【讨论】:

    【解决方案3】:

    经过数小时的研究,我找到了解决我最初问题的方法:

    我正在尝试以“SYSDBA”身份连接,然后在我的 C++ 应用程序中创建一个用户。在运行 create 命令之前,与 SYSDBA 的连接似乎已关闭。

    我没有分别运行这两个命令,而是使用管道在命令行中执行 sqlplus 命令。

    • @echo CREATE USER "<username>" PROFILE "DEFAULT" IDENTIFIED BY "<userpassword>" ACCOUNT UNLOCK; | CONNECT sys/<syspassword>@<datasource> AS SYSDBA

    C++ 代码调用命令的方式如下:

    strcpy(szProcName,"@echo CREATE USER \"");
    strcat(szProcName,userName);
    strcat(szProcName,"\" PROFILE \"DEFAULT\" IDENTIFIED BY \"");
    strcat(szProcName,Password);
    strcat(szProcName,"\" ACCOUNT UNLOCK; | sqlplus sys/");
    strcat(szProcName,Sys_Password);
    strcat(szProcName,"@");
    strcat(szProcName,info.szServerName);
    strcat(szProcName," AS SYSDBA");
    
    system(szProcName);
    

    【讨论】: