当我尝试从我的应用程序运行 SQL 映射时,我得到一个无效的列名。基本上我有两个独立的映射文件,它们基本上做同样的事情,除了创建一个不同名称的列。请注意,我故意留下了 DROP TABLE 来说明这个问题。我知道这是一种不好的做法,但我正在寻找为什么会发生这种情况。此后,我们通过显式删除每个 SQL 映射中的表来纠正此行为。
查询1:
<select id="Query1" parameterClass="query1Criteria">
IF Object_Id('tempdb..##severity') IS NOT NULL
BEGIN
DROP TABLE ##severity
END
CREATE TABLE ##severity( valueCode VARCHAR(255) NOT NULL, displayOrder INT NOT NULL)
INSERT INTO ##severity
SELECT DISTINCT valueCode,MAX(displayOrder) FROM DataDictionaryValue
WHERE zoneID = #zoneID# AND categoryCode = 'SEVERITY'
GROUP BY valueCode
SELECT valueCode FROM ##severity
</select>
查询 2:
<select id="Query2" parameterClass="query2Criteria">
IF Object_Id('tempdb..##severity') IS NOT NULL
BEGIN
DROP TABLE ##severity
END
CREATE TABLE ##severity( severityCode VARCHAR(255) NOT NULL, displayOrder INT NOT NULL)
INSERT INTO ##severity
SELECT DISTINCT valueCode,MAX(displayOrder) FROM DataDictionaryValue
WHERE zoneID = #zoneID# AND categoryCode = 'SEVERITY'
GROUP BY valueCode
SELECT severityCode FROM ##severity
</select>
从应用程序中,我运行 Query1。执行得很好,我看到了在 SQL Management Studio 中创建的临时表。然后我执行 Query2,并获得以下堆栈跟踪:
org.springframework.jdbc.BadSqlGrammarException: SqlMapClient operation; bad SQL grammar []; nested exception is com.ibatis.common.jdbc.exception.NestedSQLException:
--- The error occurred in com/test/model/safety/reports/Query2Map.xml.
--- The error occurred while applying a parameter map.
--- Check the Query2.getResults-InlineParameterMap.
--- Check the statement (query failed).
--- Cause: java.sql.SQLException: Invalid column name 'severityCode'.
at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.translate(SQLErrorCodeSQLExceptionTranslator.java:276)
at org.springframework.orm.ibatis.SqlMapClientTemplate.execute(SqlMapClientTemplate.java:212)
at org.springframework.orm.ibatis.SqlMapClientTemplate.executeWithListResult(SqlMapClientTemplate.java:249)
at org.springframework.orm.ibatis.SqlMapClientTemplate.queryForList(SqlMapClientTemplate.java:296)
at com.test.model.BaseSqlMapDao.executeQueryForList(BaseSqlMapDao.java:53)
at com.test.model.safety.reports.Query2SqlMapDao.getOpenIssues(Query2SqlMapDao.java:124)
at com.test.model.safety.reports.Query2SqlMapDao.getResults(Query2SqlMapDao.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
如果我在 SMS 中运行 Query2 的 SQL,它将正确执行。事实上,这两个查询都将在 SMS 中正确执行。我不了解 iBatis 的详细工作原理,但是 iBatis 似乎看到了在 Query1 中创建的临时表,并针对该模式验证了 Query2 的语法,在这种情况下会抛出无效的列名异常。然而,这意味着 iBatis 保留对临时表的引用,这与 SQL 服务器范式相矛盾,其中临时表的范围仅限于连接。
谁能解释这里发生了什么?