带有命名参数问题的 NHibernate CreateSQLQuery()

fur*_*ier 2 oracle nhibernate ado.net parameterized-query

在我的情况下,为什么命名或位置查询参数不适用于 NHibernate?

认为以下陈述是正确的:

在 Oracle 数据库 X 和 Y 版本 11.2.0.3.0 上,存在由“MyPassword”标识的角色“MyRole”,并授予我连接的用户。

这是一些代码:

public void SetRole(string roleName, string rolePassword)
{
    if (HasRoleBeenSet) return;
    try
    {
        session.CreateSQLQuery("SET ROLE ? IDENTIFIED BY ?")
               .SetString(0, roleName)
               .SetString(1, rolePassword)
               .ExecuteUpdate();
        HasRoleBeenSet = true;
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

SetRole("MyRole", "MyPassword");
Run Code Online (Sandbox Code Playgroud)

抛出以下异常:

NHibernate.Exceptions.GenericADOException:无法执行本机批量操作查询:SET ROLE?由 ? [SQL: SET ROLE :p0 IDENTIFIED BY :p1] ---> System.Data.OracleClient.OracleException: ORA-01937: 角色名称丢失或无效

当我使用 Toad 套件中包含的 SQLMonitor 时,发送到数据库的 SQL 如下所示SET ROLE ? IDENTIFIED BY ?,错误Error occurred: [1937] (ORA-01937: missing or invalid role name)显示如下。

当我查看 FNH 自己生成的带有参数的查询时,它们看起来像这样:

SchemaName.errorHandler.logError(:v0);

:1=['The error message']
Run Code Online (Sandbox Code Playgroud)

但是当我手动创建查询时情况并非如此 CreateSQLQuery()

好的,下一个代码示例是这样的:

...
session.CreateSQLQuery("SET ROLE :roleName IDENTIFIED BY :rolePassword")
       .SetString("roleName", roleName)
       .SetString("rolePassword", rolePassword)
       .ExecuteUpdate();
...
Run Code Online (Sandbox Code Playgroud)

输出以下错误(相同的错误):

NHibernate.Exceptions.GenericADOException: 无法执行本机批量操作查询: SET ROLE :roleName IDENTIFIED BY :rolePassword [SQL: SET ROLE :p0 IDENTIFIED BY :p1] ---> System.Data.OracleClient.OracleException: ORA-01937:缺少或无效的角色名称

第三个代码示例:

...
session.CreateSQLQuery(string.Format("SET ROLE {0} IDENTIFIED BY {1}", 
                       roleName, 
                       rolePassword))
       .ExecuteUpdate();
...
Run Code Online (Sandbox Code Playgroud)

在 Oracle 数据库 X 上,这产生了奇迹,在 Oracle 数据库 Y 上,这不起作用,并给了我这个错误:

NHibernate.Exceptions.GenericADOException: 无法执行本机批量操作查询: SET ROLE MyRole IDENTIFIED BY MyPassword [SQL: SET ROLE MyRole IDENTIFIED BY MyPassword] ---> System.Data.OracleClient.OracleException: ORA-00933: SQL 命令不正确结束

我尝试;在语句的末尾添加一个分号,但这会invalid character出错。

如果我像这样在密码周围添加双引号,它突然也适用于 Oracle 数据库 Y

 ...
session.CreateSQLQuery(string.Format("SET ROLE {0} IDENTIFIED BY \"{1}\"", 
                       roleName, 
                       rolePassword))
       .ExecuteUpdate();
...
Run Code Online (Sandbox Code Playgroud)

问题是这不是一个很好的解决方案,因为 FNH 现在会在记录的异常中溢出密码。我不知道这里有什么问题,这里没有明确的问题,因为我不知道该问什么,然后尖叫寻求帮助,并希望有人能对此有所了解。

在评论中进行了一些讨论后,我尝试了以下操作:

 ...
session.CreateSQLQuery(string.Format("SET ROLE {0} IDENTIFIED BY :rolePassword", 
                       roleName)) 
       .SetString("rolePassword", rolePassword)
       .ExecuteUpdate();
...
Run Code Online (Sandbox Code Playgroud)

我试过 :named 和 ? (位置)参数,带单引号,双引号,似乎没什么用。

这段代码抛出了著名的ORA-00933: SQL command not properly ended错误

Pap*_*ndy 5

尝试使用 .SetParameter() 而不是 SetString()。我目前正在使用这样的东西,它的工作原理:

var cases = Session.CreateSQLQuery(sql)
            .SetParameter("someID",thisIsMyValue)
            .SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean<SomeDTO>())
            .List<SomeDTO>();
Run Code Online (Sandbox Code Playgroud)

SQL 如下所示:

var sql = "SELECT fieldA, fieldB FROM myTable WHERE myTable.ID = :someID"
Run Code Online (Sandbox Code Playgroud)