SQLExpress Stored Procedure in QT - Conversion failed when converting - c++

I seem to keep getting 'conversion' errors when calling and passing values into a stored procedure....
Im trying to write a dead simple procedure to insert data collected from a form here:
void orderform::on_btnSave_clicked()
{
dbhandler().TestEntry(ui->edtOrderDate->date().toString());
};
this is the code in the dbhandler.cpp:
void dbhandler::TestEntry(QString PltfrmOrderDate)
{
QSqlQuery query;
query.prepare("{CALL [DSDB].[dbo].[Test](PltfrmOrderDate)}");
query.bindValue("#PltfrmOrderDate", PltfrmOrderDate);
if(!query.exec())
qDebug() << query.lastError();
}
** Just a note, I know this is a date and that i can use QDate but that also returns a conversion error - Please see below **
The stored procedure:
USE [DSDB]
GO
/****** Object: StoredProcedure [dbo].[Test] Script Date: 1/20/2022 7:37:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[Test]
-- Add the parameters for the stored procedure here
#PltfrmOrderDate nvarchar
AS
BEGIN
INSERT INTO [dbo].[OrdersTable]
(
PltfrmOrderDate
)
VALUES
(
#PltfrmOrderDate
)
END
So, when i run my code like this I get the following error:
QODBCResult::exec: Unable to execute statement: "[Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting date and/or time from character string."
QSqlError("241", "QODBC3: Unable to execute statement", "[Microsoft][ODBC SQL Server Driver][SQL Server]Conversion failed when converting date and/or time from character string.")
now to address the before sated QDate issue, That was how i had it innitially with the code as follows:
void orderform::on_btnSave_clicked()
{
dbhandler().TestEntry(ui->edtOrderDate->date());
};
dbhandler.cpp:
void dbhandler::TestEntry(QDate PltfrmOrderDate)
{
QSqlQuery query;
query.prepare("{CALL [DSDB].[dbo].[Test](PltfrmOrderDate)}");
query.bindValue("#PltfrmOrderDate", PltfrmOrderDate);
if(!query.exec())
qDebug() << query.lastError();
}
and finally the Stored Procedure:
USE [DSDB]
GO
/****** Object: StoredProcedure [dbo].[Test] Script Date: 1/20/2022 7:37:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[Test]
-- Add the parameters for the stored procedure here
#PltfrmOrderDate date
AS
BEGIN
INSERT INTO [dbo].[OrdersTable]
(
PltfrmOrderDate
)
VALUES
(
#PltfrmOrderDate
)
END
and this resulted in the following error:
QODBCResult::exec: Unable to execute statement: "[Microsoft][ODBC SQL Server Driver][SQL Server]Error converting data type nvarchar to date."
QSqlError("8114", "QODBC3: Unable to execute statement", "[Microsoft][ODBC SQL Server Driver][SQL Server]Error converting data type nvarchar to date.")
What i dont understand is why is there conversions happening.... I'm passing a YYYY-MM-DD date into a YYYY-MM-DD date format, and QT documents seems to suggest that the format/data type is supported.
I ran into the same issue using Double form QT into Money in SQL, Int from QT into Int in SQL and even Bool in QT into Bit in SQL.
I'm sure its something small that I'm missing but its the first time I'm trying to use this and cant seem to find the issue!

For the first example, never declare nvarchar without length. As a stored procedure parameter, that becomes nvarchar(1), which means any string passed in gets truncated silently to a single character. An easy way to debug this yourself would have been to call the procedure manually with the same arguments and simply PRINT #PltfrmOrderDate; instead of INSERT. This will have printed 2 for any date this century.
Always use YYYYMMDD since YYYY-MM-DD is not a safe format in SQL Server - it can be interpreted as YYYY-DD-MM depending on your language settings and any data type it hits via implicit or explicit conversion. It may be worth showing us exactly how C++ is presenting PltfrmOrderDate to SQL Server.
Lots more background on using date and time data in SQL Server here: Dating Responsibly

So I have managed to resolve this by using QDateTime instead of QDate.
Here the input has changed from date to datetime
void orderform::on_btnSave_clicked()
{
dbhandler().TestEntry(ui->edtOrderDate->dateTime());
};
Function parameter changed from QDate to QDateTime, as well as the ":" for the parameter in the query.prepare statement and the query.bindValue statement was missing
void dbhandler::TestEntry(QDateTime PltfrmOrderDate)
{
QSqlQuery query;
query.prepare("{CALL [DSDB].[dbo].[Test](:PltfrmOrderDate)}");
query.bindValue(":PltfrmOrderDate", PltfrmOrderDate);
if(!query.exec())
qDebug() << query.lastError();
}
In the SP all that had to change was date to datetime
USE [DSDB]
GO
/****** Object: StoredProcedure [dbo].[Test] Script Date: 1/20/2022 7:37:33 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- =============================================
-- Author: <Author,,Name>
-- Create date: <Create Date,,>
-- Description: <Description,,>
-- =============================================
ALTER PROCEDURE [dbo].[Test]
-- Add the parameters for the stored procedure here
#PltfrmOrderDate datetime
AS
BEGIN
INSERT INTO [dbo].[OrdersTable]
(
PltfrmOrderDate
)
VALUES
(
#PltfrmOrderDate
)
END

Related

IICS - populate TIMESTAMP_TZ column with generated value

I am trying to populate TIMESTAMP_TZ column in Snowflake using the Informatica IICS from the Taskflow. In the taskflow I am using function fn:current-dateTime() which I am trying then in the mapping to convert to TIMESTAMP_TZ using the to_date() function but I am getting error
MAPPING> TE_7002 [2023-01-17 11:07:50.987] Transformation stopped due to a fatal error in the mapping. The expression [To_Date($$inp_load_dttm)] contains the following errors [<<PM Parse Error>> [$$inp_load_dttm)]: Invalid date value string: >>>2023-01-17T16:06:58.019Z<<<.
... To_Date(>>>>$$inp_load_dttm<<<<)].
MANAGER> PETL_24005 [2023-01-17 11:07:50.988] Starting post-session tasks. : (Tue Jan 17 11:07:50 2023)
fn:current-dateTime() returns date (ref 1). to_date expects a string (ref 2). Here in this case you should not try to conver a date to date - it should simply work. If what you need is just the date, without the time, try using fn:current-date().

Calling or using oracle array package in oracle apex

I want to calling oracle array package in oracle apex page process.
My package "CREATE OR REPLACE PACKAGE SBPA.DPG_SBPA_ITEM_SUB_CAT AS
/..........................................................................
Program Purpose : SBPA_ITEM_SUB_CAT_ENTRY
Process Execution Time :
Generate By : Morshed
Generate Date : 27-Feb-2020
Modifyed Date :
...................................................................../
TYPE RefCursor is REF CURSOR;
TYPE Array_Item_Sub_Id IS TABLE OF SBPA_ITEM_SUB_CAT.ITEM_SUB_ID % TYPE INDEX BY BINARY_INTEGER;
TYPE Array_Item_Sub_Code IS TABLE OF SBPA_ITEM_SUB_CAT.ITEM_SUB_CODE % TYPE INDEX BY BINARY_INTEGER;
TYPE Array_Item_Sub_Desc IS TABLE OF SBPA_ITEM_SUB_CAT.ITEM_SUB_DESC % TYPE INDEX BY BINARY_INTEGER;
TYPE Array_Item_Cat_Code IS TABLE OF SBPA_ITEM_SUB_CAT.ITEM_CAT_CODE % TYPE INDEX BY BINARY_INTEGER;
TYPE Array_RowStatus IS TABLE OF VARCHAR2(5) INDEX BY BINARY_INTEGER;
PROCEDURE DPD_SBPA_ITEM_SUB_CAT (O_Status OUT NUMBER,
P_Item_Sub_Id IN Array_Item_Sub_Id,
P_Item_Sub_Code IN Array_Item_Sub_Code,
P_Item_Sub_Desc IN Array_Item_Sub_Desc,
P_Item_Cat_Code IN Array_Item_Cat_Code,
P_RowStatus IN Array_RowStatus,
P_USER VARCHAR2);
PROCEDURE DPD_SBPA_ITEM_SUB_CAT_GRID (Cur_Data OUT RefCursor);
END DPG_SBPA_ITEM_SUB_CAT;
/"
And Package body "CREATE OR REPLACE PACKAGE BODY SBPA.DPG_SBPA_ITEM_SUB_CAT AS
/..........................................................................
Program Purpose : SBPA_ITEM_SUB_CAT_ENTRY
Process Execution Time :
Generate By : Morshed
Generate Date : 27-Feb-2020
Modifyed Date :
...................................................................../
PROCEDURE DPD_SBPA_ITEM_SUB_CAT (O_Status OUT NUMBER,
P_Item_Sub_Id IN Array_Item_Sub_Id,
P_Item_Sub_Code IN Array_Item_Sub_Code,
P_Item_Sub_Desc IN Array_Item_Sub_Desc,
P_Item_Cat_Code IN Array_Item_Cat_Code,
P_RowStatus IN Array_RowStatus,
P_USER VARCHAR2) IS
V_DataType VARCHAR2(20) :='ITEM_SUBCAT_SAVE';
V_ErrDesc VARCHAR2(500);
BEGIN
/*O_Status :=1;*/
FOR I IN P_Item_Sub_Desc.FIRST..P_Item_Sub_Desc.LAST
LOOP
IF P_RowStatus(I)=1 THEN
INSERT INTO SBPA_ITEM_SUB_CAT
(ITEM_SUB_ID, ITEM_SUB_CODE, ITEM_SUB_DESC, ITEM_CAT_CODE, STATUS, CREATE_DATE, CREATE_BY) VALUES
(SBPA_ITEM_SUB_ID_SEQ.NEXTVAL,'ITMSC-'||LPAD(SBPA_ITEM_SUB_CODE_SEQ.NEXTVAL,4,'0'),P_Item_Sub_Desc(I),P_Item_Cat_Code(I),'A',SYSDATE,P_USER);
ELSIF P_RowStatus(I)=2 THEN
UPDATE SBPA_ITEM_SUB_CAT SET
ITEM_SUB_DESC=P_Item_Sub_Desc(I),
Item_Cat_Code=P_Item_Cat_Code(I),
UPDATE_BY=P_User,
UPDATE_DATE =SYSDATE
WHERE Item_Sub_Code=P_Item_Sub_Code(I);
ELSIF P_RowStatus(I)=3 THEN
DELETE FROM SBPA_ITEM_SUB_CAT
WHERE Item_Sub_Code=P_Item_Sub_Code(I);
END IF;
END LOOP;
COMMIT;
EXCEPTION WHEN OTHERS THEN ROLLBACK;
/* O_Status :=0;*/
V_ErrDesc:=SUBSTR(SQLERRM,1,500);
INSERT INTO SBPA_ERROR_LOG
(RUN_ID, DATA_TYPE, ERROR_DESC, STATUS, RUN_DATE, RUN_BY) VALUES
(SBPA_RUN_ID_SEQ.NEXTVAL,V_DataType,V_ErrDesc,'E',SYSDATE,P_User);
COMMIT;
END DPD_SBPA_ITEM_SUB_CAT;
PROCEDURE DPD_SBPA_ITEM_SUB_CAT_GRID (Cur_Data OUT RefCursor) IS
BEGIN
OPEN CUR_DATA FOR
SELECT ITEM_SUB_ID, ITEM_SUB_CODE, ITEM_SUB_DESC,S.ITEM_CAT_CODE,C.ITEM_CAT_DESC FROM SBPA_ITEM_SUB_CAT S,SBPA_ITEM_CAT C
WHERE S.ITEM_CAT_CODE=C.ITEM_CAT_CODE
ORDER BY ITEM_SUB_ID DESC;
END DPD_SBPA_ITEM_SUB_CAT_GRID;
END DPG_SBPA_ITEM_SUB_CAT;
/"
This database code. So how can i call this package in oracle apex tabular form. Please help me..
(1) Create a button, so the processing(DML) will be performed on click of the button.
(2) Button Action -> Submit Page.
(3) Create a page Process
Point -> Processing.
Tabular Form -> Select your tabular form.
Pl/SQL Code -> Begin
package_name.procedure_name(parameters);
END;
(4) When Button Pressed: Select the created button.
(5) Execution Scope: For Created and Modified rows.

How to use fromString() with currentDate()

I'm trying to get current date from the system clock and change its format (i.e. to this format dd/MM/yyyy). After that I need to set QDateEdit using setDate(). My problem is that using fromString() with QDate::currentDate() returns an invalid date. This is the piece of code regarding this issue
QDate date = QDate::currentDate().fromString("dd/MM/yyyy");
qDebug() << date.toString(); // <-- returns empty string
StartDateEdit->setDate(date); // <-- adding invalid date shows 1-1-2000
My system clock has this format M/d/yyyy in Windows 10. Any suggestions?
QDate::currentDate() is a static function, this returns the current date, the object stores the date, not the format. If you want to display the form: "dd/MM/yyyy" you must use the setDisplayFormat function of QDateEdit.
QDate date = QDate::currentDate();
StartDateEdit->setDate(date);
StartDateEdit->setDisplayFormat("dd/MM/yyyy");
Note:The fromString function converts a string to QDate indicating the format of the string.

QDateTime::fromString returns invalid Date, what am I missing?

I have some code that reads a datetime from a sqlite database, the datetime is returned as a string. when I try to convert it to a date using QDateTime::FromString it returns an invalid date. Below is the time as returned from the database and conversion.
Why is this failing to parse?
// -this is the value returned from the DB currentServerTime=2012-01-17 19:20:27.0
QString format("yyyy/MM/dd hh:mm:ss");
QString qCurrentServerTime(currentServerTime);
now = QDateTime::fromString(qCurrentServerTime, format);
No expert in QT, but if QDateTime::fromString() works as one would (reasonably) expect and according to this, you're not using the correct pattern.
You indicate the string read from the sqllite database is like "2012-01-17 19:20:27.0", then your format should be like yyyy-MM-dd HH:mm:ss.z.
In detail:
Your separator should by '-' not '/' (as you show in the example)
The time seems to be in 24 hours format (19 -> 7 p.m.) (so use HH instead of hh)
You have one digit for milliseconds, so add .z.

Database commit not quick enough for Coldfusion process

I have the following Coldfusion process:
My code makes a database call to the proc CommentInsert (this inserts a comment, and then calls an event insert proc about the comment being added called EventInsert)
I then call Event.GetEventByCommentId(commentId)
The result is no records returned, as the EventInsert hasn't finished adding the event record triggered by CommentInsert in Step 1.
I know this is the case, because if I create a delay between steps 1 and 2, then a recordset IS returned in step 2.
This leads me to believe that the read in step 2 is happening too quickly, before the event insert has committed in step 1.
My question is, how do tell the Coldfusion process to wait till Step 1 has completed before doing the read in Step 2??
Step one and step two are tow totally separate methods.
Code:
<cfset MessageHandlerManager = AddComment(argumentCollection=arguments) />
<cfset qEvents = application.API.EventManager.GetEventFeed(commentId=MessageHandlerManager.GetReturnItems()) />
Also, just let me add that the commentId being passed is valid. I have checked.
Another way to look at it:
Given this code:
<!--- Calls CommentInsert proc, which inserts a comment AND inserts an
event record by calling EventInsert within the proc --->
<cfset var newCommentId = AddComment(argumentCollection=arguments) />
<cfloop from="1" to="1000000" index="i">
</cfloop>
<!--- Gets the event record inserted in the code above --->
<cfset qEvent =
application.API.EventManager.GetEventFeed(commentId=newCommentId ) />
When I run the above code, qEvent comes back with a valid record.
However, when I comment out the loop, the record is coming back
empty.
What I think is happening is that the CommentInsert returns the new
comment Id, but when the GetEventFeed function is called, the
EventInsert proc hasn't completed in time and no record is found.
Thus, by adding the loop and delaying a bit, the event insert has time
to finish and then a valid record is returned when GetEventFeed is
called.
So my question is, how do I prevent this without using the loop.
UPDATE:
Here are the two stored procs used:
DELIMITER $$
DROP PROCEDURE IF EXISTS `CommentInsert` $$
CREATE DEFINER=`root`#`%` PROCEDURE `CommentInsert`(
IN _commentParentId bigint,
IN _commentObjectType int,
IN _commentObjectId bigint,
IN _commentText text,
IN _commentAuthorName varchar(100),
IN _commentAuthorEmail varchar(255),
IN _commentAuthorWebsite varchar(512),
IN _commentSubscribe tinyint(1),
IN _commentIsDisabled tinyint(1),
IN _commentIsActive tinyint(1),
IN _commentCSI int,
IN _commentCSD datetime,
IN _commentUSI int,
IN _commentUSD datetime,
OUT _commentIdOut bigint
)
BEGIN
DECLARE _commentId bigint default 0;
INSERT INTO comment
(
commentParentId,
commentObjectType,
commentObjectId,
commentText,
commentAuthorName,
commentAuthorEmail,
commentAuthorWebsite,
commentSubscribe,
commentIsDisabled,
commentIsActive,
commentCSI,
commentCSD,
commentUSI,
commentUSD
)
VALUES
(
_commentParentId,
_commentObjectType,
_commentObjectId,
_commentText,
_commentAuthorName,
_commentAuthorEmail,
_commentAuthorWebsite,
_commentSubscribe,
_commentIsDisabled,
_commentIsActive,
_commentCSI,
_commentCSD,
_commentUSI,
_commentUSD
);
SET _commentId = LAST_INSERT_ID();
CALL EventInsert(6, Now(), _commentId, _commentObjectType, _commentObjectId, null, null, 'Comment Added', 1, _commentCSI, Now(), _commentUSI, Now());
SELECT _commentId INTO _commentIdOut ;
END $$
DELIMITER ;
DELIMITER $$
DROP PROCEDURE IF EXISTS `EventInsert` $$
CREATE DEFINER=`root`#`%` PROCEDURE `EventInsert`(
IN _eventTypeId int,
IN _eventCreateDate datetime,
IN _eventObjectId bigint,
IN _eventAffectedObjectType1 int,
IN _eventAffectedObjectId1 bigint,
IN _eventAffectedObjectType2 int,
IN _eventAffectedObjectId2 bigint,
IN _eventText varchar(1024),
IN _eventIsActive tinyint,
IN _eventCSI int,
IN _eventCSD datetime,
IN _eventUSI int,
IN _eventUSD datetime
)
BEGIN
INSERT INTO event
(
eventTypeId,
eventCreateDate,
eventObjectId,
eventAffectedObjectType1,
eventAffectedObjectId1,
eventAffectedObjectType2,
eventAffectedObjectId2,
eventText,
eventIsActive,
eventCSI,
eventCSD,
eventUSI,
eventUSD
)
VALUES
(
_eventTypeId,
_eventCreateDate,
_eventObjectId,
_eventAffectedObjectType1,
_eventAffectedObjectId1,
_eventAffectedObjectType2,
_eventAffectedObjectId2,
_eventText,
_eventIsActive,
_eventCSI,
_eventCSD,
_eventUSI,
_eventUSD
);
END $$
DELIMITER ;
Found it. Boiled down to this line in the EventManager.GetEventFeed query:
AND eventCreateDate <= <cfqueryparam cfsqltype="cf_sql_timestamp" value="#Now()#" />
What was happening was the MySql Now() function called in the EventInsert proc was a fraction later than the Coldfusion #Now()# being used in the query. Therefore the line of code excluded that record.Also, why it was only happening when comments were added quickly.
What a biatch. Thanks for the input everyone.
Let me get this straight :
You call a MySQL SP which does an insert which then calls another SP to do another insert.
There's no return to ColdFusion between those two? Is that right?
If that's the case then the chances are there's a problem with your SP not returning values correctly or you're looking in the wrong place for the result.
I'm more inclined towards there being a problem with the MySQL SPs. They aren't exactly great and don't really give you a great deal of performance benefit. Views are useful, but the SPs are, frankly, a bit rubbish. I suspect that when you call the second SP from within the first SP and it returns a value its not being correctly passed back out of the original SP to ColdFusion, hence the lack of result.
To be honest, my suggestion would be to write two ORM functions or simple cfqueries in a suitable DAO or service to record the result of the insert of comment first and return a value. Having returned that value, make the other call to the function to get your event based on the returned comment id. (ColdFusion 8 will give you Generated_Key, ColdFusion 9 is generatedkey, I'm not sure what it'll be in Railo, but it'll be there in the "result" attribute structure).
Thinking about it, I'm not even sure why you're getting the event based on the commentid just entered. You've just added that comment against an event, so you should already have some data on that event, even if its just the ID which you can then get the full event record/object from without having to go around the house via the comment.
So over all I would suggest taking a step back and looking at the data flow you're working with and perhaps refactor it.