Речь идет о проверке повторяющихся строк после вставки.Я знаю, что вы скажете, почему бы не проверить сначала, прежде чем вставлять, но мы не можем сделать это по некоторым причинам.Мы используем Oracle 12c.
При нахождении более чем одной записи (номер транзакции и поставщик уникальны), первая запись с самое раннее время должна быть передана как статус «Успешно», адругие записи с последним временем должны быть отклонены как статус «Дублировать».
См. рисунок ниже.
Этот запрос кажется полезным, но иногда он не находит дубликатстрока.Когда я запускаю консольное приложение (C #) для загрузки 1000 данных, я получаю 2 дубликата из 1000. В производстве у нас получилось менее 15 дубликатов из 50 000. Я знаю, это неплохо, но есть ли способ сделатьлучше, чем этот запрос?ВСЕХ ДУБЛИКОВ ВСЕ!
БД Oracle, похоже, вышла из-под контроля, или я что-то не так с этим запросом?Должны ли мы создать индекс для этого запроса?Любой совет?
function checkDuplicate(i_vendor varchar2,i_transactionnumber varchar2, i_txId
raw) return number
is
transactionId raw(16);
o_result number;
BEGIN
select tx.id into transactionId from (select tx.id,row_number() over (order by tx.trans_time asc) as seqnum
from test_tx_log tx
where tx.transactionnumber = i_transactionnumber and lower(tx.vendor) = lower(i_vendor)) tx where seqnum = 1;
o_result := CASE transactionId = i_txId WHEN true THEN 1 ELSE 0 END;
return o_result;
END;
Мой стол:
Create TABLE test_tx_log
(
id RAW(16) not null,
status VARCHAR2 (300) NOT NULL,
trans_time TIMESTAMP NOT NULL,
receiptnumber VARCHAR2 (100) NULL,
transactionnumber VARCHAR2 (120) NULL,
customerreference VARCHAR2 (100) NULL,
vendor VARCHAR2 (100) NULL
) ;
C #
public bool CheckDuplicate3()
{
DbConnection connection = null;
try
{
connection = GetFactory().CreateConnection();
if (connection != null)
{
connection.ConnectionString = "user id=XXXX;password=XXXX;data source=XXXX";
connection.Open();
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = "mca_test_package.checkDuplicate";
command.CommandType = CommandType.StoredProcedure;
command.AddParameter("o_result", DbType.Decimal, 0, ParameterDirection.ReturnValue);
command.AddParameter("i_vendor", DbType.String, tx.Vendor);
command.AddParameter("i_transactionnumber", DbType.String, tx.TransactionNumber.Trim());
command.AddParameter("i_txId", DbType.Binary, tx.Id.ToByteArray(), ParameterDirection.Input, 16);
command.ExecuteNonQuery();
var result = Convert.ToInt32(command.Parameters["o_result"].Value);
if (result == 1)
{
tx.status = "Success";
Console.WriteLine("No Duplicate {0}", tx);
}
else
{
Console.WriteLine("Duplicate {0}", tx);
tx.status = "RejectedDuplicate";
}
}
using (DbCommand command = connection.CreateCommand())
{
command.CommandType = CommandType.Text;
command.CommandText = "update test_tx_log tx set tx.status = :status where id = :id";
command.AddParameter("status", DbType.String, tx.status);
//command.AddParameter("id", DbType.Decimal, tx.Id);
command.AddParameter("id", DbType.Binary, tx.Id.ToByteArray());
command.ExecuteNonQuery();
}
}
return true;
}
finally
{
if (connection != null)
connection.Close();
}
}