OpenEdge progress database insert row - Beginner - progress-4gl

i need to insert new rows into my database.
OUTPUT TO c:\temp\SMLeiste_bearbeiten.csv.
DEFINE VARIABLE size AS CHARACTER NO-UNDO FORMAT "x(3)"
LABEL "Size".
for each S_Artikel
where S_Artikel.Selektion matches "KSE*"
or S_Artikel.Selektion matches "ZSE*"
or S_Artikel.Selektion matches "SSE*",
EACH BS_Zuord
where BS_Zuord.SMLeiste = "SE"
AND BS_Zuord.Owning_Obj = S_Artikel.S_Artikel_Obj
EXCLUSIVE-LOCK.
ASSIGN BS_Zuord.Merkmal = "Größe".
PUT UNFORMATTED
'First Loop - set row with Merkmal "Größe"' + '|' + STRING(BS_Zuord.Owning_Obj) + '|' + String(S_Artikel.S_Artikel_Obj)
SKIP.
END.
So the problem now is, that i don't know how to add the row with the Size without going through every item from "BS_Zuord"
one S_Artikel object has multiple BS_Zuord objects
I just want to query which S_Artikel matches my criteria and then add a BS_Zuord with equal Owning_Obj = S_Artikel_Obj
I think i might have to join the tables or something like that, but i have no idea how to do that in progress
Thanks in advance!
edit:
Do i have to replace
EACH BS_Zuord
where BS_Zuord.SMLeiste = "SE"
AND BS_Zuord.Owning_Obj = S_Artikel.S_Artikel_Obj
EXCLUSIVE-LOCK.
ASSIGN BS_Zuord.Property = "Size".
with
CREATE BS_Zuord.
BS_Zuord.OwningObj = S_Artikel_Obj.
ASSIGN BS_Zuord.Property = "Size".
**
Newest version of complete code
**
OUTPUT TO c:\temp\SMLeiste_bearbeiten.csv.
DEFINE VARIABLE groesse AS CHARACTER NO-UNDO FORMAT "x(7)"
LABEL "Groesse".
for each S_Artikel
where S_Artikel.Selektion matches "KSE*"
or S_Artikel.Selektion matches "ZSE*"
or S_Artikel.Selektion matches "SSE*",
EACH BS_Zuord
where BS_Zuord.SMLeiste = "SE"
AND BS_Zuord.Owning_Obj = S_Artikel.S_Artikel_Obj
EXCLUSIVE-LOCK.
ASSIGN BS_Zuord.Merkmal = "Size".
PUT UNFORMATTED
'Erste Schleife - Größe anlegen' + '|' + STRING(BS_Zuord.Owning_Obj) + '|' + String(S_Artikel.S_Artikel_Obj)
SKIP.
END.
for each S_Artikel
where S_Artikel.Selektion matches "KSE*"
or S_Artikel.Selektion matches "ZSE*"
or S_Artikel.Selektion matches "SSE*",
EACH BS_Zuord
where BS_Zuord.SMLeiste = "SE"
AND BS_Zuord.Merkmal = "Größe"
AND BS_Zuord.Owning_Obj = S_Artikel_Obj
EXCLUSIVE-LOCK.
IF SUBSTRING(STRING(S_Artikel.Selektion),8,1) = "/" THEN groesse = SUBSTRING(STRING(S_Artikel.Selektion),5,7).
ELSE groesse = SUBSTRING(STRING(S_Artikel.Selektion),5,3).
BS_Zuord.Auspr = groesse.
PUT UNFORMATTED
'Zweite Schleife - Größe ausfüllen' + '|' + string(S_Artikel.Artikel) + '|' + string(S_Artikel.Selektion) + '|' + STRING(groesse) + '|' + STRING(BS_Zuord.SMLeiste) + '|' + STRING (BS_Zuord.Merkmal) + '|' + STRING(BS_Zuord.Auspr)
SKIP.
END.
If i replace the part where it says
,
EACH BS_Zuord
where BS_Zuord.SMLeiste = "SE"
AND BS_Zuord.Merkmal = "Größe"
AND BS_Zuord.Owning_Obj = S_Artikel_Obj
EXCLUSIVE-LOCK.
IF SUBSTRING(STRING(S_Artikel.Selektion),8,1) = "/" THEN groesse = SUBSTRING(STRING(S_Artikel.Selektion),5,7).
ELSE groesse = SUBSTRING(STRING(S_Artikel.Selektion),5,3).
BS_Zuord.Auspr = groesse.
with yours
/* find the appropriate BS_Zuord if it exists */
exclusive-lock.
find BS_Zuord where BS_Zuord.SMLeiste = "SE" and BS_Zuord.Owning_Obj = S_Artikel.S_Artikel_Obj no-error.
/* if it does not already exist create it and initialize the key */
if not available BS_Zuord then
do:
create BS_Zuord.
assign
BS_Zuord.SMLeiste = "SE"
BS_Zuord.Owning_Obj = S_Artikel.S_Artikel_Obj
.
end.
/* set the property field */
BS_Zuord.Property = "Size".
and comment the second for each out
this message will appear:
It says "for the Property (in my case Merkmal) "Größe" no "Ausprägung" (this is the actual value of the property "Merkmal". The Value '' is not allowed.
http://i.stack.imgur.com/FDL4S.png
So 1 S_Artikel has multiple BS_Zuord with different "Merkmal". Every "Merkmal" has multiple values.
If i run the working code, it Runs for each S_Artikel x-Merkmal times and says if, for example, a S_Artikel has 6 "Merkmal" it creates the correct "Merkmal" with "Größe" as value and then it trys 5 times more to create it but it says it is existent. Then the second for each auto creates the values that will be filled in in BS_Zuord.Auspr.
I hope you understood what i try to tell you. English is not my native language :(

I think this is what you are trying to do:
/* loop through S_Artikel records matching criteria */
for each S_Artikel no-lock where
where S_Artikel.Selektion matches "KSE*"
or S_Artikel.Selektion matches "ZSE*"
or S_Artikel.Selektion matches "SSE*":
/* find the appropriate BS_Zuord if it exists */
find BS_Zuord exclusive-lock where BS_Zuord.SMLeiste = "SE" and BS_Zuord.Owning_Obj = S_Artikel.S_Artikel_Obj no-error.
/* if it does not already exist create it and initialize the key */
if not available BS_Zuord then
do:
create BS_Zuord.
assign
BS_Zuord.SMLeiste = "SE"
BS_Zuord.Owning_Obj = S_Artikel.S_Artikel_Obj
.
end.
/* set the property field */
BS_Zuord.Property = "Size".
end. /* end of loop */
(This assumes that BS_Zuord.SMLeiste and BS_Zuord.Owning_Obj form a unique key.)

Exactly. Remove the
EACH BS_Zuord
where BS_Zuord.SMLeiste = "SE"
AND BS_Zuord.Owning_Obj = S_Artikel.S_Artikel_Obj
EXCLUSIVE-LOCK.
ASSIGN BS_Zuord.Property = "Size".
as it will change the value of ALL BS_Zuord records that match the loop criteria.
Plus, the second EACH will cycle the records you already have. Since you want to create a new, the CREATE and ASSIGN you posted last should do the trick.
If the primary key and mandatory fields in the table are supplied accordingly, but assuming you just need the pk from your code, that code you supplied seems to do what you want, as per your explanation.

Related

PostgreSQL query - typecasting

Performing PostgreSQL query
when searching from two lists for matches in a database i receive the following error:
ProgrammingError: operator does not exist: character varying ~~ text[]
LINE 1: ...FROM public."Phosphosite_table" WHERE "GENE_NAME" LIKE ARRAY...
^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
my code is the following:
start = time.time()
input_file = "az20.tsv"
names = []
residuelist = []
kinase = []
fclist = []
with open(input_file, "r") as data:
data = csv.reader(data, delimiter='\t')
next(data, None)
for row in data:
data = row[0:6]
if "(" in data[0]:
name = data[0].split("(")[0]
residue1 = data[0].split("(")[1]
residue = residue1.split(")")[0]
fc = data[3]
else:
pass
if "_" in name:
name = name.split("_")[0]
if residue != "None":
names.append(str(name))
residuelist.append(str(residue))
fclist.append(fc)
genename = names
location = residuelist
connection = pg.connect(HAHAHA)
cur = connection.cursor()
cur.execute('SELECT "KINASE_NAME" FROM public."Phosphosite_table" WHERE "GENE_NAME" LIKE %s and "RESIDUE" LIKE %s',\
(genename, location))
query = cur.fetchall()
print query
connection.close()
end = time.time()
print str((end - start)/60) + " Minutes"
I have done some research and it appears that PostgreSQL does not perform any typecasting. However, I thought it would be a comparison of a string against a string, which, I changed before appending to my list. Does anyone have any advice?
Connor
However, I thought it would be a comparison of a string against a string
The part character varying ~~ text[] of the error message tells you, that you are comparing a string ("character varying") with an array ("text[]").
If you want to compare a single value with all elements of an array you need to use the ANY operator:
WHERE "GENE_NAME" LIKE any(%s)
assuming that %s is passed as native Postgres array from your code (which seems to be the case given the error message).

Index and length must refer to a location within the string.?

My input strings are
inputData = "99998UNKNOWN"
inputData = "01000AMEBACIDE/TRICHOM/ANTIBAC 1"
inputData = "34343AMEBACIDE/TRICHOM/ANTIBACSADWA1"
ID = inputData.Substring(0,5);
Name = inputData.Substring(5,30);
Level = inputData.Substring(35,1);
I am getting the below error,
Index and length must refer to a location within the string.
I can understand , the error is due to the length that specified in substring for "Name" is not matching with first input.
Is there any way to handle this issue with any input length?
One approach is to add a "sentinel" suffix to the end of the string before taking substrings. Now you can add it to the data string before taking substrings from it. As long as the suffix has sufficient length, you would never get an index/length exception:
var padded = inputData.PadRight(32);
ID = padded.Substring(0, 5).Trim();
Name = padded.Substring(5, 30).Trim();
Level = padded.Substring(30, 1).Trim();
However, now your code should check if ID, Name, or Level is empty.

After searching in a database how to display the result field values in an editor widget using progress 4gl

Accept a customer number and then output the details of each order and items to an editor widget.
Display them in the editor widget ( editor-1 as object name).
define temp-table ttcustomer
field custnum like customer.cust-num
field cname like customer.name
field orders like order.order-num
field items like item.item-num
field itemname like item.item-name .
find first customer WHERE customer.cust-num = input f1 NO-LOCK .
create ttcustomer .
assign
ttcustomer.custnum = customer.cust-num
ttcustomer.cname = customer.name.
for each order WHERE Order.cust-num = input f1 NO-LOCK .
assign
ttcustomer.orders = order.order-num.
for each order-line where order-line.order-num = order.order-num no-lock.
for each item where item.item-num = order-line.item-num no-lock.
assign
ttcustomer.items = item.item-num
ttcustomer.itemname = item.item-name.
end.
end.
end.
I have no idea why you would want to display that on an editor. So I'll assume you want to concatenate the info you gathered in the for each loop into an editor.
So after the last end, you could do this:
define variable editor-1 as character view-as editor.
for each ttcustomer:
assign editor-1 = editor-1 + ttcustomer.items + ' ' + ttcustomer.itemname + chr(13).
end.
display editor-1.
If chr(13) doesn't work to skip a line, try chr(10).
PS: An editor is really probably not the widget you want to display this. I'd use a browse. But since the question asks for an editor, there.
PS2: You didn't assign the other fields you put on the temp-table, so I'm not displaying them. But it's just a matter of adding them to the assign line above, not forgetting the spaces, dashes or whatever you'd like to use as a separator.

VFP 5 COPY TO command

I need to copy my cursor information into text file that is encoded using UTF-8.
My current command was :-
COPY TO (FILE NAME) DELIMITED WITH CHARACTER ";"
By default the text file was saved into ANSI, how can I make it save into UTF-8?
EDIT: I am using VFP 5.
I'm not sure , try using StrConv()
strconv(filetostr(FILE NAME),10)
1.Convert all Character and Memo fields into UTF-8:
update table1 set field1=STRCONV(field1, 9)
This converts all non-ANSI characters into UTF-8 encoding.
Export it using your COPY TO command.
To expand on Oleg's suggestion, you can cycle through all fields in the given table by...
USE C:\SomePath\YourTable.dbf
*/ Get list of all fields in the table's structure
lnF = AFIELDS( laF, "YourTable" )
lcUpdFlds = ""
*/ Prepare a field for allowing comma between multiple fields
*/ but first time in is the "SET" command instead.
lcNextFld = "set "
FOR lnI = 1 TO lnF
*/ Is it a character-based field
IF laF[ lnI, 2] = "C" OR laF[ lnI, 2] = "M"
lcFld = laF[ lnI, 1]
lcUpdFlds = lcUpdFlds + lcNextFld + lcFld + " = STRCONV( " + lcFld + ", 9) "
*/ Any subsequent character based fields will have a COMMA
*/ added between them.
lcNextFld = ", "
ENDIF
ENDFOR
update YourTable &lcUpdFlds
Modified to do ONE update command and hit ALL columns vs running multiple updates... Especially on a LARGER table

Create byte ranges for to match keys starting with a particular letter

I'm doing HBase range scans, and I need to return all rows that begin with a particular letter. Given a single letter as input, how do I create the correct startRow and endRow keys?
val letter = "s"
val startRow = letter
val endRow = (letter.charAt(0) + 1).toChar.toString