为什么命名或位置查询参数在我的情况下不适用于NHibernate?
请考虑以下陈述:
在Oracle数据库X和Y版本11.2.0.3.0上,角色“MyRole”存在 由“MyPassword”标识并授予我所连接的用户 如
以下是一些代码:
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");
引发以下异常:
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']
但是,当我使用CreateSQLQuery()
好的下一个代码示例如下:
...
session.CreateSQLQuery("SET ROLE :roleName IDENTIFIED BY :rolePassword")
.SetString("roleName", roleName)
.SetString("rolePassword", rolePassword)
.ExecuteUpdate();
...
哪个输出以下错误(相同的错误):
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();
...
在Oracle数据库X上,这会产生奇迹,在Oracle数据库Y上这不能很好地工作并且给我这个错误:
NHibernate.Exceptions.GenericADOException: 无法执行本机批量操作查询:SET ROLE MyRole IDENTIFIED BY MyPassword [SQL:由MyPassword识别的SET ROLE MyRole] ---> System.Data.OracleClient.OracleException:ORA-00933:SQL命令未正确结束
我尝试在语句末尾添加分号;
,但这会导致invalid character
错误。
如果我在这样的密码周围添加双引号,它也会突然适用于Oracle数据库Y
...
session.CreateSQLQuery(string.Format("SET ROLE {0} IDENTIFIED BY \"{1}\"",
roleName,
rolePassword))
.ExecuteUpdate();
...
问题是这不是一个很好的解决方案,因为FNH现在会在记录的异常中泄露密码。我不知道这里的问题是什么,这里没有干净的问题,因为我不知道该问什么,然后尖叫寻求帮助,希望有人可以对此有所了解。
在评论中进行了一些讨论后,我尝试了以下内容:
...
session.CreateSQLQuery(string.Format("SET ROLE {0} IDENTIFIED BY :rolePassword",
roleName))
.SetString("rolePassword", rolePassword)
.ExecuteUpdate();
...
我试过两个:命名和? (位置)参数,单引号,双引号,似乎没有什么可行的。
此代码抛出了着名的ORA-00933: SQL command not properly ended
错误
答案 0 :(得分:2)
尝试使用.SetParameter()而不是SetString()。我目前正在使用类似的东西,它可以工作:
var cases = Session.CreateSQLQuery(sql)
.SetParameter("someID",thisIsMyValue)
.SetResultTransformer(NHibernate.Transform.Transformers.AliasToBean<SomeDTO>())
.List<SomeDTO>();
SQL看起来像这样:
var sql = "SELECT fieldA, fieldB FROM myTable WHERE myTable.ID = :someID"