Peoplecode, SQLEXEC not retrieving correct data - oracle

<-------PeopleCode------>
Hi,
I have a SQL query that i have tried executing using both SQLEXEC and SQL.fetch() but the problem is, when I am passing the values to parameters (:1,:2...) it does not return a row but when I hardcode the values in the where clause of the query itself, it retrieves the correct value.
Can anybody help?
My query looks similar to the following sample query :
Select * from PS_rec1 where emplid=:1 and plan_type=:2
it returns no data till i hardcode the values.
I have checked the values at the back end and some data is there to be fetched. Moreover, the same query retrieves data when ran in TOAD.

Have you tried outputting your binds to a log file just before you use them in your SQL statement?
If the binds aren't working, but literals are, then perhaps your binds don't contain the values that you expect them to.
You could also try explicitly setting the binds to the values that you're expecting just before the SQL statement. This will prove that the way you're passing in the binds is working correctly.

It required another update to the same record to get the values fetched in SQL exec.
M not sure what was the problem but i guess it might be that the previous update did not write the changes to the db even after an explicit commit.

Ok, you need to put your exact SQLExec statement in the question.
But, do you really have "Select * ..." in a SQLExec? How many columns are in your table? Since you mention the where clause, is your statement
SQLExec("select * from PS_rec where emplid=:1 and plan_type=:2", &var1, &var2, &vartocontainthewholerow);
Which will work in a SQL tool (toad) but probably does not work in AE or any type of Peoplecode program.
Now if your table has three columns, should you not have something like this:
SQLExec("select emplid, plan_type, column3 from PS_rec where emplid = :1 and plan_type=:2", &emplidIn, &plan_typeIn, &emplidOut, &plan_typeOut, &column3Out);
Notice that with three columns in the table that emplid and plan_type are two of them, you need to list all the columns you want, not asterisks '*'. Kind of silly to select the emplid and plan_type though.

Related

Oracle 19: Why IN gets converted to Exist in explain plan and any suggestions around it

Please see image below:
As per that the IN query got converted to Exists in explain plan. Any reason for that? does it mean Oracle automatically converts IN to Exists?
Also any suggestion to reduce the cost? this statement is a part of a SP and it receives ~ separated string ('123') for example (63278~63282~63285~63288~63291~63296~63299~63302~63305~63308~63311~63314~63319~63322~63325~63329~63332~63253~63256~63260~63264~63267~63272~63275~63279~63283~63286~63289~63292~63297~63300~63303~63306~63309~63312~63315~63320~63323~63326~63330~63333~63269~63258~63277~63294~63317~63262~63270~63281~63295~63318~63328~63254~63257~63261~63265~63268~63273~63276~63280~63284~63287~63290~63293~63298~63301~63304~63307~63310~63313~63316~63321~63324~63327~63331~63334) in query. It takes around 10 to 15 mins to execute.
How can we generate explain plan for entire stored proc? We are using Oracle 19.
Thank you in advance.
IN clause retrieves all records which match with the given set of values. It acts as multiple OR conditions. IN clause scans all rows fetched from the inner query.
But, EXISTS is a Boolean operator that returns either True or False. Its used in combination to a sub-query. If the subquery returns any row, it returns True else False. If the result of data large inside the IN clause, then not recommended using IN. For getting high performance most time uses EXISTS vs IN. For that Oracle and PostgreSQL converts your IN to EXISTS
Since you are doing the job in a PL/SQL procedure you could create (out of the procedure) a GLOBAL TEMPORARY TABLE with DELETE ON COMMIT, in the procedure you INSERT in this table the result of the sub select with the CONNECT BY, then your replace the SELECT ... CONNECT BY by a SELECT in the temporary table. The temp table will be emptied at the end of the procedure and this method is session safe. And you have benefit of the index and probably a better plan. You could also compare the UPDATE with 2 ones: splitting the OR condition on 2 statements.

How to create Interactive/Classic Report with dynamic SQL?

I'm running Apex 19.2 and I would like to create a classical or interactive report based on dynamic query.
The query I'm using is not known at design time. It depends on an page item value.
-- So I have a function that generates the SQL as follows
GetSQLQuery(:P1_MyItem);
This function may return something like
select Field1 from Table1
or
Select field1,field2 from Table1 inner join Table2 on ...
So it's not a sql query always with the same number of columns. It's completely variable.
I tried using PL/SQL function Body returning SQL Query but it seems like Apex needs to parse the query at design time.
Has anyone an idea how to solve that please ?
Cheers,
Thanks.
Enable the Use Generic Column Names option, as Koen said.
Then set Generic Column Count to the upper bound of the number of columns the query might return.
If you need dynamic column headers too, go to the region attributes and set Type (under Heading) to the appropriate value. PL/SQL Function Body is the most flexible and powerful option, but it's also the most work. Just make sure you return the correct number of headings as per the query.

Select distinct results, when using with() operator in Yii

How can I select only distinct records, from relational table, when using with() operator in Yii?
I'm getting my models (records) like that:
$probe = Probes::model()->with(array
(
'user',
'results',
'results.answer',
'survey',
'survey.questions',
'survey.questions.question',
'survey.questions.question.answers',
'manager'
))->findByPk($id);
I want to make sure, that survey.questions relation returns only distinct records. But it seems, that I don't see any way to achieve this (or I'm blind / not educated enough).
When giving relational table name / alias as array:
'results.question'=>array('alias'=>'results_question'),
the distinct key is not among those, that can be used in such array (as modifier).
I tried very ugly, bumpy way of changing select from default * to DISTINCT *:
'survey.questions'=>array('select'=>'distinct'),
But this has (of course?) failed:
Active record "SurveysQuestions" is trying to select an invalid column "distinct". Note, the column must exist in the table or be an expression with alias.
How can I achieve this (seemed so obvious and easy), if it is possible at all this way (using with())? If not, then -- please, advice how to get distinct records in relational table any way (other than manually filtering results using foreach, what I'm doing right now, and what is ugly).
You could set CDbCriteria::distinct to true:
'survey.questions'=>array('distinct'=>true),

Firebird queries using chars/varchar

I am using SQLManager Lite for firebird and it was impossible so far to write a query which would do an operation on char/varchar columns. Character set is win1252.
A query like
select * from Person where name = 'John'
won't return any results despite the fact that the record exists in the database. A similar query on a numerical column works just fine.
AM I am missing anything here?
Also, this query runs fine from my application. The only issue is that I would like to be able to run it within SQLManager Lite too. As a side note, values for char and varchar columns are not displayed properly within the same SQLManager Lite.
change to like
select * from Person where name like 'John'

Get the Affected Row from PL-SQL

I am using ODP.Net and run the PL/SQL Command to merge the table in the Oracle 10G database.
My command is as follow:
MERGE INTO TestTable t
USING (SELECT 2911 AS AR_ID FROM dual) s
ON (t.AR_ID = s.AR_ID)
WHEN MATCHED THEN
UPDATE SET t.AR_VIUAL_IMPAIRMENT = 1
WHEN NOT MATCHED THEN
INSERT (AR_S_REF)
VALUES ('abcdef');
SELECT sql%ROWCOUNT FROM dual;
The Merge command runs successfully and update/insert as I want. The problem is I want to know how many records are updated.
When I run the above statement, "ORA-00911: invalid character error".
Please advise me how I could get the affected rows back. Thanks million.
You're mixing up a few things: a MERGE statement is a plain SQL command while PL/SQL code is always delimited by BEGIN/END (and optional DECLARE). Furthermore, SQL%ROWCOUNT is a PL/SQL variable that cannot occur outside of PL/SQL.
And I don't quite understand whether you ran the MERGE and the SELECT statement with two separate or a common ODP.NET call.
Anyway, the solution is straightfowrad with ODP.NET: Execute the MERGE command with OracleCommand.ExecuteNonQuery(). This method returns the number of affected rows.
One thing you could do is put your code in a PLSQL function that returns %ROWCOUNT.
Then call this function from ODP.net setting the command type to stored procedure and using the ExecuteLiteral method which is going to return you the row count as an object instance you can cast as an int.
It is not possible to return just the "updated" row count.
(as already mentioned the row count is the number of affected (inserted and updated) rows)
there is a good discusion on ask tom: http://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:122741200346595110

Resources