How to do a table property validation in Matlab? - matlab

When I create an object in a constructor,
myTable property is constructed on the fly, for example, from csv file. I want to have some validation for that property as I have for myInt.
Do you happen to know how to do that? In the future, I guess I will need a per-column validation...
classdef BigObject
properties
myInt (1,1) double {mustBeNonnegative, mustBeInteger} = 0;
myTable (?,?) table {mustBeGreaterThan(table{1}.Variables,1), mustBeLessThan(table{2} ? ,2)} = table;
I tried selecting columns
myTable table {mustBeGreaterThan(table{1},1)} = table;
myTable table {mustBeGreaterThan(table{2}.Variables,2)} = table;
myTable table {mustBeGreaterThan(table.Variables,3)} = table;

The best way to achieve this is to write your own simple property validation function. You can build this on top of existing functions. So, you might do something like this:
%% Base case - passes
t = table((1:10).', 'VariableNames',{'MyVar'});
someFcn(t);
%% Fails because value is negative
t2 = table(-(1:10).', 'VariableNames',{'MyVar'});
someFcn(t2)
% Example function that uses validation
function someFcn(t)
arguments
t {mustHavePositiveVar(t, 'MyVar')}
end
end
% Custom validation function
function mustHavePositiveVar(t, varName)
try
mustBeA(t, 'table');
mustBeMember({varName}, t.Properties.VariableNames)
mustBePositive(t.(varName));
catch E
error('Input must be a table with a variable named %s that is all positive', varName)
end
end
Note there's a nuance if you use the class constraint syntax at the same time as a property validation function - namely that the property gets assigned and type-coerced before the validation functions run. So if you're going to validate the type of an input, you need to omit the class constraint (otherwise the input might simply be coerced to the correct type anyway).

Related

How to pick up data from row and put it into tPostgresqlInput?

I have a requets which giving me an ids. I need to iterate them into another request, so I have a sheme like this: scheme
In tPostgresqlInput I have this code rc.id = upper('18ce317b-bf69-4150-b880-2ab739eab0fe') , but instead of id I need to put smthn like globalMap.get(row4.id). How did I do this?
Apparently this is a syntax issue
Try with :
"select * FROM table LEFT JOIN table on parameter JOIN table on parameter
WHERE 1=1 AND
column = 'content'
AND upper(rc.id) = upper('"+((String)globalMap.get("row4.id")) +"')"
Expressions in tDBInput should always begin and end with double quotes.
Don't forget to cast globalMap.get() with the type of your element (here I put String)
.equals is not a DB function but a java function. I have replaced it with '='
Let me know if it's better

CREATE FUNCTION failed because a column name is not specified for column 1. error for the Multiple parameter of function

Wanted to create the multiple parameter of function but it gives me this error:
CREATE FUNCTION failed because a column name is not specified for
column 1.
Code below:
create function dmt.Impacted(
#nameOfColumn varchar , #nameOfParam varchar)
returns table
as
return
(select
case when '['+#nameOfColumn+']' is null or len(rtrim('['+#nameOfColumn+']')) = 0
then Convert(nvarchar(2),0)
else
#nameOfParam end from employee) ;
As the error message clearly said, the column in the returned result need a name. Either give it an alias in the SELECT like
SELECT CASE
...
END a_column_name
...
or define it in the declaration of the return type as in
...
RETURNS TABLE
(a_column_name nvarchar(max)
...
As you can see in the second form you have to specify a data type. As your current code doesn't make much sense now I cannot figure out what is the right one there. You'd need to amend it.
Note, that len(rtrim('['+#nameOfColumn+']')) = 0 is never true as len(rtrim('['+#nameOfColumn+']')) is either NULL, when #nameOfColumn is NULL or at least 2 because of the added brackets.
If #nameOfColumn is supposed to be a column name you shouldn't use varchar (especially without a length specified for it) but sysname which is a special type for object names.
Either way you should define a length for #nameOfColumn and #nameOfParam as just varchar without any length means varchar(1), which is probably not what you want. And maybe instead of varchar you want nvarchar.
You may also want to look into quotename().
Define name of column in SELECT statement :
(select case when '['+#nameOfColumn+']' is null or
len(rtrim('['+#nameOfColumn+']')) = 0
then Convert(nvarchar(2),0)
else #nameOfParam
end as name_column -- define column name
from employee)
Also, your function parameter has no data length, by default it will accept only 1 character #nameOfColumn varchar , #nameOfParam varchar & rest will trim.

how to use identity and concatenate it into the other columns of the table?

If I generate an identity for a table on the column cust-id, I want the next column userid to be cust-id+CID.
E.g. 000000001CID, 0000000002CID
What sql do I include for this?
Similarly if I have 00001 in the column Cust-id and abcd in the column section, the 3rd column must have value 00001abcd
Please let me know the solutions
You just need to create a trigger. Something like
CREATE TRIGGER A
BEFORE INSERT ON TABLE B
REFERENCING NEW AS N
FOR EACH ROW
BEGIN
SET N.userid = N.CUST_ID + N.CID ;
IF (N.CUST_ID = '00001' AND N.SECTION = 'abcd') THEN
SET N.THIRD = N.CUST_ID + N.SECTION
END IF;
END #
By the way, generating values in column shows that your module is not normalize, and sometimes this is a source of errors.

calculation in postgresql function

I'm trying to create function that serves as replacement for postgresql sum function in my query.
query itself it LOOONG and something like this
SELECT .... sum(tax) as tax ... from (SUBQUERY) as bar group by id;
I want to replace this sum function with my own which alters the end value by tax calculation.
So I created pgsql function like this:
DECLARE
v double precision;
BEGIN
IF val > 256 THEN
v := 256;
ELSE
v := val;
END IF;
RETURN (v*0.21)/0.79;
END;
That function uses double precision as input. Using this function gives me error though:
column "bar.tax" must appear in the GROUP BY clause or be used in an aggregate function
So I tried to use double precision[] as input type for function - in that case the error was telling me that there was no postgresql function matching the name and given input type.
So is there a way to replace sum function in my query by using pgsql functions or not - I don't want to change any other parts of my query unless I really, Really, REALLY have to.
Look into CREATE AGGREGATE for aggregate functions. And in your expression you can do something like sum(LEAST(tax,256)*21/79) if I read you right.

Universal function module to retrieve SAP table data

What is the best way to access table data from a SAP system?
I tried it with it RFC_READ_TABLE, but this RFC returns the data in concatenated form within a single column and has a size restriction for row data.
Is there a better way to access SAP data in generic form without creating custom RFCs into the system?
I am searching for a standard RFC solution, not a custom script.
If I understand your question right, you want to read a table, but at time of programming, you don't know which table.
With Select * from (tablename)you can read with a dynamic table name.
The target field can be defined dynamic with create data.
An example (untested, currently I have no access to an SAP-system):
DATA: lv_tablename TYPE string,
ev_filelength TYPE i.
lv_tablename = 'mara'. "e.g. a parameter
DATA dref TYPE REF TO data.
CREATE DATA dref TYPE TABLE OF (lv_tablename).
FIELD-SYMBOLS: <wa> TYPE ANY TABLE.
ASSIGN dref->* to <wa>.
SELECT * FROM (lv_tablename) INTO TABLE <wa>. "Attention for test, may be large result
"<wa> is like a variable with type table mara
TYPES: BEGIN OF t_bseg,
*include structure bseg.
bukrs LIKE bseg-bukrs,
belnr LIKE bseg-belnr,
gjahr LIKE bseg-gjahr,
buzei LIKE bseg-buzei,
mwskz LIKE bseg-mwskz, "Tax code
umsks LIKE bseg-umsks, "Special G/L transaction type
prctr LIKE bseg-prctr, "Profit Centre
hkont LIKE bseg-hkont, "G/L account
xauto LIKE bseg-xauto,
koart LIKE bseg-koart,
dmbtr LIKE bseg-dmbtr,
mwart LIKE bseg-mwart,
hwbas LIKE bseg-hwbas,
aufnr LIKE bseg-aufnr,
projk LIKE bseg-projk,
shkzg LIKE bseg-shkzg,
kokrs LIKE bseg-kokrs,
END OF t_bseg.
DATA: it_bseg TYPE STANDARD TABLE OF t_bseg INITIAL SIZE 0,
wa_bseg TYPE t_bseg.
DATA: it_ekko TYPE STANDARD TABLE OF ekko.
*Select all fields of a SAP database table into in itab
SELECT *
FROM ekko
INTO TABLE it_ekko.
Try this snippet of RFC_READ_TABLE to get data in structured form:
DATA: oref TYPE REF TO cx_root,
text TYPE string,
obj_data TYPE REF TO data.
lt_options TYPE TABLE OF rfc_db_opt,
ls_option TYPE rfc_db_opt,
lt_fields TYPE TABLE OF rfc_db_fld,
ls_field TYPE rfc_db_fld,
lt_entries TYPE STANDARD TABLE OF tab512.
FIELD-SYMBOLS: <fs_tab> TYPE STANDARD TABLE.
TRY.
ls_option-text = `some query`.
APPEND ls_option TO lt_options.
ls_field-fieldname = 'PARTNER'.
APPEND ls_field TO lt_fields.
ls_field-fieldname = 'TYPE'.
APPEND ls_field TO lt_fields.
ls_field-fieldname = 'BU_GROUP'.
APPEND ls_field TO lt_fields.
ls_field-fieldname = 'BU_SORT1'.
APPEND ls_field TO lt_fields.
ls_field-fieldname = 'TITLE'.
APPEND ls_field TO lt_fields.
CALL FUNCTION 'RFC_READ_TABLE' DESTINATION dest
EXPORTING
query_table = 'BUT000'
TABLES
options = lt_options
fields = lt_fields
data = lt_entries.
CATCH cx_root INTO oref.
text = oref->get_text( ).
MESSAGE text TYPE 'E'.
ENDTRY.
IF lt_entries IS NOT INITIAL.
CREATE DATA obj_data TYPE TABLE OF but000.
ASSIGN obj_data->* TO <fs_tab>.
CREATE DATA obj_data TYPE but000.
ASSIGN obj_data->* TO FIELD-SYMBOL(<fs_line>).
LOOP AT lt_entries ASSIGNING FIELD-SYMBOL(<wa_data>).
LOOP AT lt_fields ASSIGNING FIELD-SYMBOL(<fs_fld>).
ASSIGN COMPONENT <fs_fld>-fieldname OF STRUCTURE <fs_line> TO FIELD-SYMBOL(<lv_field>).
IF <lv_field> IS ASSIGNED AND sy-subrc IS INITIAL.
<lv_field> = <wa_data>-wa+<fs_fld>-offset(<fs_fld>-length).
ENDIF.
APPEND <fs_line> TO <fs_tab>.
ENDLOOP.
ENDLOOP.
ENDIF.
IF <fs_tab> IS NOT INITIAL.
"Bingo!
ENDIF.