我正在使用Oracle的ADO.Net提供程序来执行由分号分隔的2个select语句。我正在使用system.Data.OracleClient数据提供程序。但是,似乎Oracle不喜欢分号,因为当ADO.Net代码运行时,我得到一个无效的字符错误。有关如何解决这个问题的任何想法,因为我必须在相同的数据库行程中运行两个SELECT语句?
string sql = @"
WITH
x AS
(
SELECT
RowNum AS RowIndex,
CAST(Contract_Id AS VARCHAR2(1000)) Contract_Id,
Contract_Number,
Name AS Contract_Name,
Contract_Number
|| ' '
|| Name AS Contract_Description,
Eff_Date,
Expiry_Date
FROM
contracts
WHERE
contract_number LIKE :ContractSearchText
OR name LIKE :ContractSearchText
)
SELECT
*
FROM
x
WHERE
RowIndex >= :StartingRowIndex
AND RowIndex < (:StartingRowIndex + :MaxRows) ;
SELECT
COUNT(*)
FROM
contracts
WHERE
contract_number LIKE :ContractSearchText
OR name LIKE :ContractSearchText;
";
更新
亚历克斯的回复是我能找到的最佳答案。但是,我提出了另一个替代答案,我不确定该表是被击中两次还是只有一次。备用查询依赖于使用计数派生表创建CROSS JOIN。可能有人可以告诉我,在这个替代答案中该表只被击中一次吗? WITH
x AS
(
SELECT
RowNum AS RowIndex,
CAST(Contract_Id AS VARCHAR2(1000)) Contract_Id,
Contract_Number,
Name AS Contract_Name,
Contract_Number
|| ' '
|| Name AS Contract_Description,
Eff_Date,
Expiry_Date
FROM
vha_int_contract
WHERE
contract_number LIKE :ContractSearchText
OR name LIKE :ContractSearchText
),
y as ( select count(distinct contract_id) TotalCount from x)
SELECT
*
FROM
x cross join y
WHERE
RowIndex >= :StartingRowIndex
AND RowIndex < (:StartingRowIndex + :MaxRows)
答案 0 :(得分:2)
通常不能在调用中运行多个SQL语句,并且不一定需要切换到PL / SQL。看起来你正试图在同一时刻计算匹配行的数量,我想你可以做一些类似'结果1到5的30'的事情。虽然你可以做两个单独的调用,但是他们可能会得到不一致的结果,因为另一个事务可以在它们之间提交(所以你不需要'25到30的29',或者部分的最后一页像'25到29 30' ?)。
您可以将总计数作为每个返回行中的额外字段,这有点多余,但不会花费更多 - 实际上更少,因为您只打了一次表,没有两个单独的查询。这使用analytic function
count
版本的{{3}},并带有一个空的over
子句,因为在这种情况下你想要计算所有内容:
SELECT x.*, COUNT(1) OVER () Range_Count
FROM
(
SELECT
RowNum AS RowIndex,
CAST(Contract_Id AS VARCHAR2(1000)) Contract_Id,
Contract_Number,
Name AS Contract_Name,
Contract_Number
|| ' '
|| Name AS Contract_Description,
Eff_Date,
Expiry_Date,
COUNT(1) OVER () Total_Count
FROM
contracts
WHERE
contract_number LIKE :ContractSearchText
OR name LIKE :ContractSearchText
) x
WHERE RowIndex >= :StartingRowIndex
AND RowIndex < (:StartingRowIndex + :MaxRows)
我在这里做了两件事,只是为了好玩。您需要的是内部查询COUNT(1) OVER () Total_Count
;这会在返回的每一行上为您提供Total_Count
列,其值等于原始单独的COUNT(*)
查询所找到的值。我已经在外部查询上添加了一个COUNT(1) OVER () Range_Count
,它将显示该范围内有多少条记录 - 在您到达最后一页'页面'之前将是:Max_Rows
。可能没有用,您可以在处理行时对行进行计数,但只是真的可以显示它们。
您目前在查询中没有任何排序,这意味着您可能无法获得预期的结果。我建议你在内部查询中添加ORDER BY
子句,或者将RowNum
更改为ROW_NUMBER() OVER(ORDER BY Contract_ID)
以坚持分析主题。
不完全确定你的意见是什么。如果您想要与每个Contract_Id
匹配的记录数,可以在内部查询中添加另一个术语:
COUNT(1) OVER (PARTITION BY Contract_Id) Contract_Id_Count
如果您想要不同Contract_Id
值的总数,请添加以下内容:
COUNT(DISTINCT Contract_Id) OVER () Contract_Id_Count
答案 1 :(得分:1)
除了能够为操作提供更好的方法之外,我们是否可以说ado.net不喜欢分号?我运行一些批量查询,通常是一个创建表,做一些事情,然后删除表。 在T-SQL中,上述情况是可能的,因为SQL Server不需要使用分号来终止大多数操作中的语句,这与终结者必须使用的Oracle不同。
我目前唯一可以考虑解决瘦问题的方法是使用存储过程(不像T-SQL那样好或容易编码),但它确实允许执行批处理语句。