Record.Insert() peoplecode not creating an exception on unique constraint error - peoplesoft

The peoplecode is straightforward, instantiate the record object, read from an XML file, assign values to the rec.fields, and then perform an insert followed by a commitwork().
The only thing that I can see that would be a reason for the data from the XML to not be inserted is that it is the second use of the same SSN in the file. The table it's being inserted into has BRANCH_ID, CREATION_DT, and SSN as the key structure. The BRANCH_ID and the CREATION_DT is static for the entire file.
Here's the code....
You'll see below that I have tried to use a TRY/CATCH (which did not work properly, in that it never found an exception to catch), as well as simply testing the boolean return of both the insert and commitwork. The boolean approach as you see throws an exception, but it does not have a valid reason to offer as an explanation for the failed insert.
As the code is below right now, you'll see that I'm simply looping through and not using the boolean of the insert/commitwork or a try/catch to determine an error. The program does not stop because of this unique constraint error, which is very strange. It simply keeps going on to the next row.
Naturally, I need to be able to log into the error table that the row was not inserted because of a unique constraint. Any suggestions?
&REC1 = CreateRecord(Record.D2_PLFS_TBL);
&REC1.SetDefault();
&Node1 = &rootNode.GetElementsByTagName("LocatorData");
&Mega1File.WriteLine("THERE ARE >" | &Node1.Len | " rows in this file.");
&cDate = Substring(&cDate, 8, 2) | Substring(&cDate, 3, 5) | Substring(&cDate, 1, 2);
For &Cnt1 = 1 To &Node1.Len
rem try;
&xmlDoc1 = CreateXmlDoc(&Node1 [&Cnt1].GenXmlString());
&Mega1File.WriteLine(%This.GetElementData(&xmlDoc1, "SocialSecurityAccountNumber"));
&REC1.GetField(Field.IBTRANSACTIONID).Value = &IBTransactionId;
&REC1.GetField(Field.TRANSACTION_NBR).Value = &Cnt1;
&REC1.GetField(Field.BRANCH_ID).Value = &Branch_CD1;
&REC1.GetField(Field.CREATION_DT).Value = &cDate;
&REC1.GetField(Field.SSN).Value = %This.GetElementData(&xmlDoc1, "SocialSecurityAccountNumber");
&REC1.GetField(Field.SSN1).Value = %This.GetElementData(&xmlDoc1, "XRefSocialSecurityAccountNumber");
&REC1.GetField(Field.D2_ACCT_STATUS).Value = %This.GetElementData(&xmlDoc1, "AccountStatus");
&REC1.GetField(Field.NAME).Value = %This.GetElementData(&xmlDoc1, "MemberName");
&REC1.GetField(Field.NAME1).Value = %This.GetElementData(&xmlDoc1, "OwnerName");
&REC1.GetField(Field.D2_MBR_TYPE).Value = %This.GetElementData(&xmlDoc1, "MemberType");
&REC1.GetField(Field.D2_SPCL_HNDLNG).Value = %This.GetElementData(&xmlDoc1, "SpecialHandling");
&REC1.GetField(Field.D2_DOMFOR_CD).Value = %This.GetElementData(&xmlDoc1, "DomForeignCode");
&REC1.GetField(Field.ADDRESS1).Value = %This.GetElementData(&xmlDoc1, "Address");
&REC1.GetField(Field.COUNTRY_2CHAR).Value = %This.GetElementData(&xmlDoc1, "CountryCode");
&REC1.GetField(Field.CITY).Value = %This.GetElementData(&xmlDoc1, "CityName");
&REC1.GetField(Field.STATE).Value = %This.GetElementData(&xmlDoc1, "StateName");
&REC1.GetField(Field.POSTAL).Value = %This.GetElementData(&xmlDoc1, "ZipSuffix");
&REC1.GetField(Field.POSTAL2).Value = %This.GetElementData(&xmlDoc1, "ZipName");
&REC1.GetField(Field.BRANCH_FLAG).Value = %This.GetElementData(&xmlDoc1, "BranchOfService");
&REC1.GetField(Field.D2_RANK_RATE).Value = %This.GetElementData(&xmlDoc1, "RankRate");
&REC1.GetField(Field.UNIT_CD).Value = %This.GetElementData(&xmlDoc1, "UIC");
&REC1.GetField(Field.RETIREMENT_DT).Value = %This.GetElementData(&xmlDoc1, "RetirementTransferDate");
&REC1.Insert();
CommitWork();
/* If &REC1.Insert() Then
&Mega1File.WriteLine("INSERTED");
CommitWork();
Else
&Mega1File.WriteLine("NOT !!!!!! INSERTED");
throw CreateException(0, 0, "exception here");
End-If;
catch Exception &ex
Local Record &recError = CreateRecord(Record.D2_DRAS2_ERROR);
&Mega1File.WriteLine("Caught the ERROR >" | &ex.ToString() | "<");
&recError.IBTRANSACTIONID.Value = &IBTransactionId;
&recError.TRANSACTION_NBR.Value = &Cnt1;
&recError.SSN.Value = %This.GetElementData(&xmlDoc1, "SocialSecurityAccountNumber");
&recError.MESSAGE_NBR.Value = 0;
&recError.MESSAGE_TEXT_254.Value = "IGS-PLFS - " | &ex.ToString();
&recError.FIELDNAME.Value = "SSN";
&recError.VALUE_TEXT.Value = "Duplicate Row, Unique Constraint on SSN";
&recError.Insert();
CommitWork();
end-try;*/
End-For;

Reading PeopleBooks, it says the insert method will return a value of false if those keys already exist. Any other reason will cause program termination.
so you could write something like:
if not &REC1.insert() then
throw CreateException(0, 0, "Duplicate Insert");
End-If;

Related

azure kql parse function - unable to parse ? using regex (zero or one time)

I'm trying to parse this line:
01/11/1011 11:11:11: LOG SERVER = 1 URL = /one/one.aspx/ AccountId = 1111 MainId = 1111 UserAgent = Browser = Chrome , Version = 11.0, IsMobile = False, IP = 1.1.1.1 MESSAGE = sample message TRACE = 1
using this parse statement:
parse-where kind=regex flags=i message with
timestamp:datetime
":.*LOG SERVER = " log_server:string
".*URL = " url:string
".*AccountId = " account_id:string
".*MainId = " main_id:string
".*?UserAgent = " user_agent:string
",.*Version = " version:string
",.*IsMobile = " is_mobile:string
",.*IP = " ip:string
".*MESSAGE = " event:string
".*TRACE = " trace:string
now the thing is that sometimes I got records that has one "key=value" missing but the order of the rest of the columns remains the same.
to match all kinds of rows I just wanted to add (<name_of_colum>)? for example:
"(,.*Version = )?" version:string
but it fails everytime.
I think parse/parse-where operators are more useful when you have well formatted inputs - the potentially missing values in this case would make it tricky/impossible to use these operators.
If you control the formatting of the input strings, consider normalizing it to always include all fields and/or add delimiters and quotes where appropriate.
Otherwise, you could use the extract function to parse it - the following expression would work even if some lines are missing some fields:
| extend
timestamp = extract("(.*): .*", 1, message, typeof(datetime)),
log_server = extract(".*LOG SERVER = ([^\\s]*).*", 1, message),
url = extract(".*URL = ([^\\s]*).*", 1, message),
main_id = extract(".*MainId = ([^\\s]*).*", 1, message),
user_agent = extract(".*UserAgent = ([^,]*).*", 1, message),
version = extract(".*Version = ([^,]*).*", 1, message),
is_mobile = extract(".*IsMobile = ([^,]*).*", 1, message),
ip = extract(".*IP = ([^\\s]*).*", 1, message),
event = iff(message has "TRACE", extract(".*MESSAGE = (.*) TRACE.*", 1, message), extract(".*MESSAGE = (.*)", 1, message)),
trace = extract(".*TRACE = (.*)", 1, message)

Insert/Update R data.table into PostgreSQL table

I have a PostgreSQL database set up with a table and columns already defined. The primary key for the table is a combination of (Id, datetime) column. I need to periodically INSERT data for different Ids from R data.table into the database. However, if data for a particular (Id, datetime) combination already exists it should be UPDATED (overwritten). How can I do this using RPostgres or RPostgreSQL packages?
When I try to insert a data.table where some (Id, datetime) rows already exist I get an error saying the primary key constraint is violated:
dbWriteTable(con, table, dt, append = TRUE, row.names = FALSE)
Error in connection_copy_data(conn#ptr, sql, value) :
COPY returned error: ERROR: duplicate key value violates unique constraint "interval_data_pkey"
DETAIL: Key (id, dttm_utc)=(a0za000000CSdLoAAL, 2018-10-01 05:15:00+00) already exists.
CONTEXT: COPY interval_data, line 1
You can use my pg package that has upsert functionality, or just grab code for upsert from there: https://github.com/jangorecki/pg/blob/master/R/pg.R#L249
It is basically what others said in comments. Write data into temp table and then insert into destination table using on conflict clause.
pgSendUpsert = function(stage_name, name, conflict_by, on_conflict = "DO NOTHING", techstamp = TRUE, conn = getOption("pg.conn"), .log = getOption("pg.log",TRUE)){
stopifnot(!is.null(conn), is.logical(.log), is.logical(techstamp), is.character(on_conflict), length(on_conflict)==1L)
cols = pgListFields(stage_name)
cols = setdiff(cols, c("run_id","r_timestamp")) # remove techstamp to have clean column list, as the fresh one will be used, if any
# sql
insert_into = sprintf("INSERT INTO %s.%s (%s)", name[1L], name[2L], paste(if(techstamp) c(cols, c("run_id","r_timestamp")) else cols, collapse=", "))
select = sprintf("SELECT %s", paste(cols, collapse=", "))
if(techstamp) select = sprintf("%s, %s::INTEGER run_id, '%s'::TIMESTAMPTZ r_timestamp", select, get_run_id(), format(Sys.time(), "%Y-%m-%d %H:%M:%OS"))
from = sprintf("FROM %s.%s", stage_name[1L], stage_name[2L])
if(!missing(conflict_by)) on_conflict = paste(paste0("(",paste(conflict_by, collapse=", "),")"), on_conflict)
on_conflict = paste("ON CONFLICT",on_conflict)
sql = paste0(paste(insert_into, select, from, on_conflict), ";")
pgSendQuery(sql, conn = conn, .log = .log)
}
#' #rdname pg
pgUpsertTable = function(name, value, conflict_by, on_conflict = "DO NOTHING", stage_name, techstamp = TRUE, conn = getOption("pg.conn"), .log = getOption("pg.log",TRUE)){
stopifnot(!is.null(conn), is.logical(.log), is.logical(techstamp), is.character(on_conflict), length(on_conflict)==1L)
name = schema_table(name)
if(!missing(stage_name)){
stage_name = schema_table(stage_name)
drop_stage = FALSE
} else {
stage_name = name
stage_name[2L] = paste("tmp", stage_name[2L], sep="_")
drop_stage = TRUE
}
if(pgExistsTable(stage_name)) pgTruncateTable(name = stage_name, conn = conn, .log = .log)
pgWriteTable(name = stage_name, value = value, techstamp = techstamp, conn = conn, .log = .log)
on.exit(if(drop_stage) pgDropTable(stage_name, conn = conn, .log = .log))
pgSendUpsert(stage_name = stage_name, name = name, conflict_by = conflict_by, on_conflict = on_conflict, techstamp = techstamp, conn = conn, .log = .log)
}

Oracle Stored Procedure unable to call from ASP.NET

I have written a code in ASP.NET to fetch data from Oracle stored procedure. But I get an error when trying to fetch the data:
ORA-06550: line 1, column 7: PLS-00306: wrong number or types of arguments in call to 'USER_FEEDBACK' ORA-06550: line 1, column 7: PL/SQL: Statement ignored
Procedure code is this:
create or replace PROCEDURE user_feedback(cv_results out sys_refcursor,start_date IN VARCHAR2)
IS
BEGIN
open cv_results for
select pi.first_name || ' ' || pi.last_name initiator
......
from request_workflow w inner join request_workflow_attribute waRating
on waRating.request_workflow_id = w.row_id
and waRating.attr_name = 'UserRating'
.............
where w.date_stamp_utc between start_date and '31-dec-2015'
order by waRating.attr_value desc, eform_name;
END ;
This is my ASP.NET code:
Oracle.DataAccess.Client.OracleCommand objCmd = new Oracle.DataAccess.Client.OracleCommand();
objCmd.Connection = objConn;
objCmd.CommandText = "user_feedback";
objCmd.CommandType = CommandType.StoredProcedure;
Oracle.DataAccess.Client.OracleParameter oraP = new Oracle.DataAccess.Client.OracleParameter();
// System.Data.OracleClient.OracleParameter op = null;
oraP.OracleDbType = OracleDbType.RefCursor;
oraP.ParameterName = "cv_results";
oraP.Direction = System.Data.ParameterDirection.Output;
oraP.ParameterName = "start_date";
oraP.OracleDbType = OracleDbType.Varchar2;
oraP.Value = "01-Dec-2015";
oraP.Direction = System.Data.ParameterDirection.Input;
objCmd.Parameters.Add(oraP);
objConn.Open();
objCmd.ExecuteReader();
objCmd.ExecuteNonQuery();
Please suggest how to make it work.
You're only creating/adding a single parameter but assigning it twice with different values resulting in just one parameter to the call.
Instead, create and add two separate parameters, something like;
var oraP1 = new Oracle.DataAccess.Client.OracleParameter();
oraP1.OracleDbType = OracleDbType.RefCursor;
oraP1.ParameterName = "cv_results";
oraP1.Direction = System.Data.ParameterDirection.Output;
objCmd.Parameters.Add(oraP1);
var oraP2 = new Oracle.DataAccess.Client.OracleParameter();
oraP2.ParameterName = "start_date";
oraP2.OracleDbType = OracleDbType.Varchar2;
oraP2.Value = "01-Dec-2015";
oraP2.Direction = System.Data.ParameterDirection.Input;
objCmd.Parameters.Add(oraP2);
It's probably because you don't Add the first parameter. Try something like this?
...
oraP.ParameterName = "cv_results";
oraP.Direction = System.Data.ParameterDirection.Output;
objCmd.Parameters.Add(oraP);
oraP = new Oracle.DataAccess.Client.OracleParameter();
oraP.ParameterName = "start_date";
...
Though, it'd be better to declare another variable for the first param if you'll be reading from that refcursor later.

Encountered "ORA-01745: invalid host/bind variable name" when using DbDataAdapter.Update() with ODP.NET

I have a table defined in oracle 11g with below statement:
CREATE TABLE "TESTUSER"."TestTableOracleWriter"
("name" VARCHAR2(100 BYTE),
"group" VARCHAR2(100 BYTE),
"number" NUMBER(*,0),
"creation" DATE,
"sliceidentifier" RAW(100),
CONSTRAINT "TESTTABLEORACLEWRITER_PK" PRIMARY KEY ("name"))
And I am using the following code snippet to update the table with content in the dataTable:
private void BatchInsert(DbConnection connection, DbTransaction transaction, DataTable dataTable, string tableName)
{
DbDataAdapter adapter = ProviderFactories.GetFactory("Oracle.DataAccess.Client").CreateDataAdapter();
DbCommand insertCommand = connection.CreateCommand();
DbParameter parameter1 = insertCommand.CreateParameter();
parameter.DbType = DbType.String;
parameter.ParameterName = "#name";
parameter.SourceColumn = "name";
insertCommand.Parameters.Add(parameter);
DbParameter parameter2 = insertCommand.CreateParameter();
parameter2.DbType = DbType.String;
parameter2.ParameterName = "#group";
parameter2.SourceColumn = "group";
insertCommand.Parameters.Add(parameter2);
DbParameter parameter3 = insertCommand.CreateParameter();
parameter3.DbType = DbType.Int32;
parameter3.ParameterName = "#number";
parameter3.SourceColumn = "number";
insertCommand.Parameters.Add(parameter3);
DbParameter parameter4 = insertCommand.CreateParameter();
parameter4.DbType = DbType.DateTime;
parameter4.ParameterName = "#creation";
parameter4.SourceColumn = "creation";
insertCommand.Parameters.Add(parameter4);
insertCommand.CommandType = CommandType.Text;
insertCommand.CommandText = "INSERT INTO \"TestTableOracleWriter\" (\"name\", \"group\", \"number\", \"creation\") VALUES (:name, :group, :number, :creation)";
insertCommand.Transaction = transaction;
insertCommand.UpdatedRowSource = UpdateRowSource.None;
adapter.InsertCommand = insertCommand;
adapter.UpdateBatchSize = 0;
adapter.Update(dataTable);
}
But sometimes the code will fail with "ORA-01745: invalid host/bind variable name", I've searched on the internet and found some materials saying it has something to do with the oracle reserve word. From the link, "name", "group" and "number" is marked as reserve word. I can change my table column names to make the code work.
But the strangest thing is that the code does not fail all the time, it only fails when dataTable cotains only one row, in other scenarios, it works as expected. Anyone has ideas about that?
You can not use key word as parameter name.
Don't use group and number as parameter name

Getting error while inserting table in database?

i am inserting table in database using table datatype with the following code:
CREATE TYPE BackUpDoctorLocationAreaRoom AS TABLE (
[RoomId] bigint,
[AreaId] bigint,
[LocationId] bigint
);
Alter proc proc_tblBackUpDoctorInsert
(
#Id uniqueidentifier='',
#BackUpDoctorId uniqueidentifier='1323e1f4-7a93-4b45-9a9b-3840c32fd6d8',
#StartDate datetime='11/08/2012',
#EndDate datetime='11/09/2012',
#StartTime datetime='22:22:22',
#EndTime datetime='01:11:11',
#CreatedBy uniqueidentifier='acf7961c-4111-49ad-a66a-ce7f9ce131bd',
#ModifiedBy uniqueidentifier='acf7961c-4111-49ad-a66a-ce7f9ce131bd',
#createdDate datetime='11/6/12 3:09:58 AM',
#ModifiedDate datetime='11/6/12 3:09:58 AM',
#tblBackUpDoctorsForRooms BackUpDoctorLocationAreaRoom READONLY
)
as
set xact_abort on
declare #newId uniqueidentifier;
set #newId = newid();
insert into tblBackUpDoctor (Id,BackUpDoctorId,StartDate,EndDate,StartTime,EndTime,CreatedBy,ModifiedBy,
createdDate,ModifiedDate,IsActive,isdeleted) values
(#newId,
#BackUpDoctorId,
#StartDate,
#EndDate,
#StartTime,
#EndTime,
#CreatedBy,
#ModifiedBy,
#createdDate,
#ModifiedDate,
1,0)
declare #IdFortblBackUpDoctorsForRooms uniqueidentifier;
set #IdFortblBackUpDoctorsForRooms = newid();
delete from tblBackUpDoctorsForRooms where BackUpRecordId=#id and Roomid in (Select roomid from #tblBackUpDoctorsForRooms)
delete from tblbackupdoctor where id=#id
insert into tblBackUpDoctorsForRooms (BackUpRecordId,Roomid,Araeid,locationid)
Select #newId,roomid,areaid,locationid from #tblBackUpDoctorsForRooms
select #newId
This is the sp in which i am using that table.
My class file's code is :
public string InsertBackUpDoctor(ClsBackUpDoctorProp objProp, DataTable dtLocAreaRoom)
{
String ConnectionString = CCMMUtility.GetCacheForWholeApplication();
String backUpRecordId = "";
SqlParameter[] param = new SqlParameter[12];
param[0] = new SqlParameter("#Id", objProp.Id);
param[1] = new SqlParameter("#BackUpDoctorId", objProp.BackUpDoctorId);
param[2] = new SqlParameter("#StartDate", objProp.StartDate);
param[3] = new SqlParameter("#EndDate", objProp.EndDate);
param[4] = new SqlParameter("#StartTime", objProp.StartTime);
param[5] = new SqlParameter("#EndTime", objProp.EndTime);
param[6] = new SqlParameter("#CreatedBy", objProp.CreatedBy);
param[7] = new SqlParameter("#ModifiedBy", objProp.ModifiedBy);
param[8] = new SqlParameter("#createdDate", CCMMUtility.GetCurrentDateTimeByTimeZone("US Mountain Standard Time"));
param[9] = new SqlParameter("#ModifiedDate", CCMMUtility.GetCurrentDateTimeByTimeZone("US Mountain Standard Time"));
param[10] = new SqlParameter("#CurrentDate", objProp.CurrentDate);
param[11] = new SqlParameter("#tblBackUpDoctorsForRooms ", dtLocAreaRoom);
backUpRecordId = SqlHelper.ExecuteScalar(ConnectionString, "proc_tblbackupdoctorInsertBackUpDoctors", param).ToString();
return backUpRecordId;
}
and here is the error which is coming when i tries to insert :
The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Table-valued parameter 12 ("#tblBackUpDoctorsForRooms"), row 0, column 0: Data type 0xF3 (user-defined table type) has a non-zero length database name specified. Database name is not allowed with a table-valued parameter, only schema name and type name are valid.
I dont know why this coming please help me..
I believe you'd have to change the way you pass your custom parameter:
Not just
param[11] = new SqlParameter("#tblBackUpDoctorsForRooms ", dtLocAreaRoom);
but rather something like
SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "#tblBackUpDoctorsForRooms";
parameter.SqlDbType = System.Data.SqlDbType.Structured;
parameter.TypeName = "BackUpDoctorLocationAreaRoom";
parameter.Value = dtLocAreaRoom;
param[11] = parameter;
try
parameter.SqlDbType = System.Data.SqlDbType.Structured;
parameter.TypeName = "BackUpDoctorLocationAreaRoom";
and in the call add
backUpRecordId = SqlHelper.ExecuteScalar(ConnectionString,CommandType.StoredProcedure
"proc_tblbackupdoctorInsertBackUpDoctors", param).ToString();

Resources