oracle forms builder pl/sql - access a column that is dervied from other columns - database

I have a view in my database that has a bunch of fields derived from other information in the database, this is how the view is defined:
create view patient_account_view AS
select patient.p_mrn,
p_fname,
p_lname,
ammount_paid,
quantity*item_cost + repeats*item_cost "ammount_owing",
(quantity*item_cost + repeats*item_cost) - ammount_paid "balance"
from patient_account,
patient,
diagnosis,
prescribed_treatment,
items_used,
item,
perscription
where patient.p_mrn = diagnosis.p_mrn AND
patient_account.p_mrn = patient.p_mrn AND
diagnosis.prescribed_treatment_id = prescribed_treatment.prescribed_treatment_id AND
prescribed_treatment.prescribed_treatment_id = perscription.prescribed_treatment_id AND
items_used.ptreatment_id = prescribed_treatment.prescribed_treatment_id AND
items_used.item_number = item.item_number;
I would like to use pl/sql to access the information in the view to stick it into a form, but I'm getting a 'bad bind variable' error. How do I access this kind of attribute without having to recalculate the information stored there?
Here is the plsql that is problematic:
DECLARE
pmrn patient.p_mrn%TYPE;
var_ptuple patient%ROWTYPE;
var_accttuple patient_account%ROWTYPE;
BEGIN
pmrn := :PATIENT_BLOCK.MRN_FIELD;
SELECT * INTO var_ptuple from patient WHERE patient.p_mrn = pmrn;
SELECT * INTO var_accttuple from patient_account_view WHERE patient_account_view.p_mrn = pmrn;
:PATIENT_BLOCK.FNAME := var_ptuple.p_fname;
:PATIENT_BLOCK.LNAME := var_ptuple.p_lname;
:PATIENT_BLOCK.BALACNCE_OWING := var_accttuple.balance;
END;

The columns of your view patient_account_view do not match exactly the columns of the table patient_account, but in your code you have:
var_accttuple patient_account%ROWTYPE;
which means when you run this:
SELECT * INTO var_accttuple from patient_account_view ...
You haven't specified which columns get mapped to which record attributes, so Oracle requires that the column list matches exactly.
In this case, I'd expect you probably want to change the definition of the variable, e.g.
var_accttuple patient_account_view%ROWTYPE;
Side note
Since you're only using one attribute from the view, you can simplify your code as follows:
SELECT balance INTO :PATIENT_BLOCK.BALACNCE_OWING
from patient_account_view WHERE patient_account_view.p_mrn = pmrn;
and you no longer need var_accttuple.

Related

How do I display Dynamics NAV table option field text values in SQL Server

Sometimes during Dynamics NAV development, it is helpful to take a quick look at the data using SQL Server. But because any fields of type option are an enumeration, all you get in SQL Server is the numeric value. I needed a quick and dirty way to get the option text values instead.
From within NAV you can read the OPTIONSTRING property of a FieldReference. This is a comma separated string. A job can be scheduled that will loop through all of the tables (Object virtual table filtered on table) by number, find the options strings and add them to a table. Then in a query you can find the option text value for the Table, Field No, and Field Value.
RecRef.OPEN(TableNo);
FOR i := 1 TO RecRef.FIELDCOUNT DO BEGIN
FieldRef := RecRef.FIELDINDEX(i);
IF FORMAT(FieldRef.TYPE) = 'Option' THEN BEGIN
optionstring := FieldRef.OPTIONSTRING;
c := NumberofOptions(optionstring);
FOR o := 1 TO c DO BEGIN
OptionsTable.INIT;
OptionsTable."Table No" := TableNo;
OptionsTable."Field No" := FieldRef.NUMBER;
OptionsTable."Option Value" := o-1;
OptionsTable."Option Text" := SELECTSTR(o, optionstring);
OptionsTable."Field Name" := FieldRef.NAME;
IF NOT OptionsTable.INSERT THEN OptionsTable.DELETE;
END;
END;
END;
To make this a little less painful, I created a macro enabled Excel file that parses the Dynamics NAV field option string into a Sql Server T-Sql Case statement. It provides a horizontal or vertical case statement and uses the field name as the column alias in Sql Server. Enjoy...
Here is a link to the Excel file
Excel File
I often get this problem. I created a table with option values (int) and names (string). The primary key is code, value. So you can use it also to resolve magicnumbers from other systems. Then you can easy join this table:
select Type, i.[Option] [Option Name]
from Object o
join [xxx$IntegerToOption] i on i.Code = 'OBJEKT TYP' and i.Integer = o.Type
order by o.Name
Output:
Type Option Name
5 Codeunit
2 Form
1 Table
2 Form
2 Form
1 Table
2 Form
5 Codeunit
3 Report

SQL - How can I return a value from a different table base on a parameter?

SQL - How can I return a value from a different table base on a parameter
First time poster, long time reader:
I am using a custom Excel function that allows be to pass parameters and build a SQL string that returns a value. This is working fine. However, I would like to choose among various tables based on the parameters that are passed.
At the moment I have two working functions with SQL statements look like this:
_______FUNCTION ONE________
<SQLText>
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'</SQLText>
_______FUNCTION TWO________
<SQLText>
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'</SQLText>
So I am using IF logic in Excel to check the first parameter and decide which function to use.
It would be much better if I could do a single SQL statement that could pick the right table based on the 1st parameter. Logically something like this:
_______FUNCTIONS COMBINED________
IF '&PARM02' = “A” THEN
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'
ELSE IF '&PARM02' = “B” THEN
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'
ELSE
DESCRIPTION = “”
Based on another post Querying different table based on a parameter I tried this exact syntax with no success
<SQLText>
IF'&PARM02'= "A"
BEGIN
SELECT PRODDTA.F0101.ABALPH as DESCRIPTION
FROM PRODDTA.F0101
WHERE PRODDTA.F0101.ABAN8 = '&PARM02'
END ELSE
BEGIN
SELECT PRODDTA.F4801.WADL01 as DESCRIPTION
FROM PRODDTA.F4801
WHERE PRODDTA.F4801.WADOCO = '&PARM02'
END</SQLText>
You could try using a JOIN statement.
http://www.sqlfiddle.com/#!9/23461d/1
Here is a fiddle showing two tables.
The following code snip will give you the values from both tables, using the Key as the matching logic.
SELECT Table1.description, Table1.key, Table2.description
from Table1
Join Table2 on Table1.key = Table2.key
Here's one way to do it. If PARM03='Use Table1' then the top half of the union will return records and vice versa. This won't necessarily product good performance though. You should consider why you are storing data in this way. It looks like you are partitioning data across different tables which is a bad idea.
SELECT PRODDTA.TABLE1.T1DESC as DESCRIPTION
FROM PRODDTA.TABLE1
WHERE PRODDTA.TABLE1.T1KEY = '&PARM02'
AND &PARM03='Use Table1'
UNION ALL
SELECT PRODDTA.TABLE2.T2DESC as DESCRIPTION
FROM PRODDTA.TABLE2
WHERE PRODDTA.TABLE2.T2KEY = '&PARM02'</SQLText>
AND &PARM03='Use Table2'

DBCheckComboBox get values in SQL Server

I have a column that is NVarChar(MAX), it contains text like this: ;0,4,6
These are the Flag values from another table.
A. I set the EditValueFormat propertie of the component to cvfIndices
B. I put the table values from Table a to a TcxDBCheckComboBox component using code like this:
Query.Active := True;
while not Query.Eof do begin
cxDBCheckComboBox1.Properties.Items.AddCheckItem(QueryCaptionField.AsString);
Query.Next;
end;
Query.Active := False;
C. I assigned a datasource to point to that column I want to hold my value when I select the values in the program the text looks like this in the database: ;0,4,6 how should I query it to find what is selected from SQL Server?
Found the answer while using cvfIndices the value saved in the database represents the index of the value in the combobox so you can query it like this:
SELECT * FROM TechCardsData
LEFT JOIN TechCardsOperations
on
CHARINDEX(CAST(TechCardsOperations.ID-1 as nvarchar(max)),TechCardsData.OperationsFlags) <> 0
and everything works :) hope this helps someone :)

Writing to different tables from writable view

I want to write to different tables depending on the state of my development (b=backup, t=testing).
The minimal example showing the problem is the following:
SELECT s.Monat FROM (
SELECT 'b' as mode, * FROM [BACKUP].IstMonat
UNION
SELECT 't' as mode, * FROM [TESTING].IstMonat
) s
where s.mode = 't' -- in the real world discovered by a sub query.
How can i create such a view that is actually writable?
Currently ...
INSERT INTO TestView(Monat) VALUES (1);
... results in ...
Msg 4406, Level 16, State 1, Line 1
Update or insert of view or function 'TestView' failed because it contains a derived or constant field.
I solved it with something like the following:
CREATE TRIGGER ModifyAllSynonyms ON [IMPORT].ImpIstMonat
INSTEAD OF INSERT
AS
IF ( EXISTS (SELECT * FROM dbo.ModeSwitch WHERE mode = 'backup') )
INSERT INTO [BACKUP].IstMonat
SELECT * FROM inserted
ELSE
INSERT INTO [TESTING].IstMonat
SELECT * FROM inserted
A (non-indexed) View cannot have two potentially writable table-targets at run-time. That's one of the reasons that Views with UNION in them are automatically read-only.
I can think of only two ways that this could be done:
View Triggers: Create a View with an INSTEAD OF Trigger that procedureally decides which table to write to, (I cannot remember if this has to be an Indexed View or not), or ...
Synonyms: Define your View's target through the use of a Synonym. Then when you want to switch it, simply redefine the synonym.

Stored Procedure with two input params and multiple matches and create view with in

I am not much strong in SQL, so looking for some help.
First I am looking for suggestion for the best way to implement this logic in SQL and then some sample code to implement.
My portal is going to connect Students and Training Providers.
Students: Select what courses (multiple) they want, type of delivery (online, class room), Industry(domain) to which the course to be targeted more, Location Preference.
Training Providers: Select what courses offering (so one record for each course), offering locations, type of delivery for each course, industries (multiple) it is targeting.
When student login:
I would like to create SP which in turn create view to store the matched records of the Training Providers data which matches that student needs of that StudentID, CourseID passed to SP
I have created the following sp ( but not included create view part as I am not sure how to do this)
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER PROCEDURE [dbo].[sp_TPsMatched2StuCourse]
-- Add the parameters for the stored procedure here
#StuID int,
#CourseID int
AS
BEGIN
Select TP.MemID,TP.PastExp,SN.DeliveryType,SN.LocPref,SN.Industry,SC.CourseID from
tbl_TrainingProvider as TP , tbl_StuCourses as SC, tbl_StuNeeds SN
where SN.CourseID = #CourseID and SN.StuID = #StuID and
SN.DeliveryType in (TP.DeliveryMode) and
SN.LocPref IN (TP.LocOffering) and
SN.Industry IN (TP.Industries)
END
--- exec sp_ELsMatched2EntProp 1, 1
Why I need to put the data is as follows:
Assume the data is stored in that dynamic view and that would be bind to datagrid. Student then select interested TPs. Then only contact details would be shared to each other and this cannot be reveresed. So I would put this interested data in another table later. Every time data changes, hence the matches. Student can change some of his/her needs or new TPs join etc so view to be temparory.
when I executed this using above command, I am not getting data though it matches few records. What is wrong I am doing.
Any help would be greatly appreciated.
You are not getting expected results because you filter out too many records in WHERE( I'm talking about this part : SN.DeliveryType in (TP.DeliveryMode) and
SN.LocPref IN (TP.LocOffering) and SN.Industry IN (TP.Industries)). I'd recommend to use JOIN ... ON instead of specifying all tables in FROM and join condition in WHERE. I'm not sure what you want exactly, but I believe you are looking for
FROM tbl_StuNeeds SN
LEFT JOIN tbl_TrainingProvider as TP ON (TP.DeliveryMode = SN.DeliveryType AND
SN.LocPref = TP.LocOffering AND TP.Industries = SN.Industry)
WHERE SN.CourseID = #CourseID and SN.StuID = #StuID
Also, there is no join conditions in your code for tbl_StuCourses as SC which results in cross-join.
Finally, why do you need a stored procedure at all? From what I see in your example, a table-valued function will work better:
CREATE FUNCTION [dbo].getTPsMatched2StuCourse(#StuID INT,#CourseID INT)
RETURNS TABLE AS
RETURN
Select .... ;

Resources