Crystal Report text functions - sapb1

i'm using ItemName field in a Crystal Report. The field contains the item name and dimensions: -
Egg Pot & Saucer 47x41cm
I wish to suppress the dimension details, leaving just the text part of the string.
I'm looking for a set of functions that could create a formula in Crystal to do this.
The issue is the there are many different syntax for the dimension part: -
65x47x30cm or 43cm or 47x41cm
The constant is that they all start with a Numeric.

I think using a combination of crystals string functions (Instr,Left,Length,Replace etc) you should be able to accomplish this.
What have you tried so far?
would any of the required info (Egg Pot & Saucer) contain numbers?
if not, find the first occurrence of a number using a loop and isNumeric
then use LEFT to return everything before that number.
Local StringVar f := {Command.ItemName} ;
local Numbervar L := length(f) ;
Local Numbervar i ;
Local StringVar s ;
for i := 1 to L do
(
( If IsNumeric(f[i]) then exit for )
);
Left ({Command.CardName},i -1)
updated with additional condition:
Local StringVar f := {Command.CardName} ;
local Numbervar L := length(f) ;
Local Numbervar i ;
Local StringVar OutPut ;
If {Command.CardName} like "* Set *" Then
f
else
(for i := 1 to L do
( If IsNumeric(f[i]) then exit for);
OutPut:= Left({Command.CardName},i -1);)

Related

Is it possible to generate a unique random alphanumeric code consisting of 5 characters using Informix or standard sql?

I'm using informix IDS server, and I have this table table1 :
Column name Type Nulls
ad_code char(5) yes
ad_value smallint yes
I would like to generate a random, unique code for field ad_code (and then store it in the ad_code field) of table table1 using sql.
Is it possible ?
It would be enough, alternatively, an alphanumeric code sequnziale, es. 00001 ... 00009 ... 0000A unique
I have tried something like this, in the case of hexadecimal values in the
field ad_code:
select first 5 ('0x'||NVL( l.ad_code, '0'))::INT + 1
from table1 as l
left outer join table1 as r on
('0x'||NVL( l.ad_code, '0'))::INT + 1 =
('0x'||NVL( r.ad_code, '0'))::INT
where
r.ad_code is null ORDER BY 1 ASC;
commit;
but is very slow despite having created an index on ad_code.
You can generate 15-bit random numbers using this pair of stored procedures:
-- #(#)$Id: random.spl,v 1.2 1997/12/08 19:31:44 johnl Exp $
--
-- Simple emulation of SRAND and RAND in SPL
-- Using random number generator suggested by C standard (ISO 9899:1990)
CREATE PROCEDURE sp_setseed(n INTEGER)
DEFINE GLOBAL seed DECIMAL(10) DEFAULT 1;
LET seed = n;
END PROCEDURE;
CREATE PROCEDURE sp_random() RETURNING INTEGER;
DEFINE GLOBAL seed DECIMAL(10) DEFAULT 1;
DEFINE d DECIMAL(20,0);
LET d = (seed * 1103515245) + 12345;
-- MOD function does not handle 20-digit values... Dammit!!
LET seed = d - 4294967296 * TRUNC(d / 4294967296);
RETURN MOD(TRUNC(seed / 65536), 32768);
END PROCEDURE;
You can use those numbers to generate a sequence of alphanumeric characters, with more or less finesse. A simple approach uses the random number modulo the number of alphanumeric characters (do you want [A-Z0-9] or [a-z0-9] or [A-Za-z0-9], or something else), and select a character each time. There is potential for unequal distributions if you are not careful (because if there are 32768 possible random numbers, and you have 36 possible characters, 8 of characters will have a 911 out of 32768 chance of being selected, while the other 28 will only have a 910 out of 32768 chance of being selected (and the problem is bigger if you use 62 characters — lower-case, upper-case and digits). There are ways to deal with that if it is a problem.
Here's the simple-minded, slightly skewed approach at work:
-- #(#)$Id: randomstring.spl,v 1.1 2018/08/27 16:43:59 jonathanleffler Exp $
--
-- Generate a random sequence of characters from given list
CREATE FUNCTION sp_randomstring(str VARCHAR(255), num INTEGER)
RETURNING VARCHAR(255) AS random_string;
DEFINE r VARCHAR(255);
DEFINE i INTEGER;
DEFINE n INTEGER;
DEFINE j INTEGER;
LET r = "";
LET n = LENGTH(str);
FOR i = 1 TO num
LET j = MOD(sp_random(), n) + 1;
LET r = r || SUBSTR(str, j, 1);
END FOR;
RETURN r;
END FUNCTION;
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 20);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 21);
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 22);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 23);
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 24);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 24);
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 23);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 22);
EXECUTE FUNCTION sp_randomstring("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", 21);
EXECUTE FUNCTION sp_randomstring("abcdefghijklmnopqrstuvwxyz0123456789", 20);
Sample output:
087TTLGDMSNXMAFL7PJG
cklp14dfk66308lxkzjyu
6JDTOJLC47UE9GWSHRBH55
gwpmrfwwwcykgqbn494bmeh
TNY3U3VMHN01UZS1GV4LOF0K
tm38v8qwqj6o0vrsh9gbb0w6
YF6QP6NT3VK5ARTFDL1N32B
vrb9pvww5cw6egsz9tniex
9OIY799Z694DBENBDFSFE
1gkj5adm3bswlo26wd5i
I didn't set the seed, so that code generates the same sequence every time. You might use a sequence to generate a new seed each time, or you might do something else to seed the generator. The seed is private to each session.

How to get insert values from a table into an array using SQL?

with dmHospital do
begin
qryHospital.SQL.Clear;
qryHospital.SQL.Add('SELECT * FROM Patients ') ;
qryHospital.SQL.Add('WHERE DoctorID = :DoctorID');
qryHospital.Parameters.ParamByName('DoctorID').Value := StrToInt(sID);
qryHospital.Open;
iCount := qryHospital.RecordCount
end;
This code displays the values I want to put into the array. However I'm not sure how to cycle through each record and to get each value from the record into the correct array. For example: I want the names from 'PatientName' and the surnames from 'PatientSurname'.
iCount is the array size.
You must loop from TDataset using While.
Some sample code:
...
var
fieldCod:TField;
Str1:String;
i, Cod:Integer;
begin
...
qryHospital.Open;
iCount := qryHospital.RecordCount;
// Create pointer to field
fieldCod := qryHospital.FieldByName('PatientCode');
// loop the recordset (while not arrive at end)
While (not qryHospital.eof) do begin
// Different modes to access table fields content
Str1 := qryHospital.FieldByName('PatientName').AsString;
i := qryHospital.Fields[1].AsInteger;
Cod := fieldCod.AsInteger;
// Add the values to your array
//...
// Next Record
qryHospital.Next;
end;
NOTE: For better performance, don't use FieldByName inside the loop (for big number of records). You can use Fields[index] or create a variable out of the loop and reference to fields.

ORACLE SQL Method Produces Warning

I'm having trouble getting the following member method to compile (count_single_buses). Would appreciate any advice on what might be wrong syntactically with my code.
CREATE OR REPLACE TYPE BodyModel2_Type AS OBJECT(
ModelID INTEGER,
ModelName VARCHAR2(45),
FloorType VARCHAR2(45),
Manufacturer VARCHAR2(45),
Length NUMBER(8,2),
Width NUMBER(8,2),
NoOfAxles INTEGER,
MEMBER FUNCTION count_single_buses(ModelID INTEGER) RETURN INTEGER);
/
CREATE OR REPLACE TYPE BODY BodyModel2_Type AS
MEMBER FUNCTION count_single_buses(ModelID INTEGER) RETURN INTEGER IS
N INTEGER;
BEGIN
N := (SELECT COUNT(BODYMODELREF) FROM SINGLEDECKBUS_TABLE S
WHERE S.BODYMODELREF = ModelID);
RETURN N;
END count_single_buses;
END;
--EDIT--
Thanks to #Ravi, I managed to solve the issue my correcting my SQL syntax and setting the resultset to a NUMBER, instead of INTEGER.
CREATE OR REPLACE TYPE BODY BodyModel_Type AS
MEMBER FUNCTION count_single_buses(thisModelID INTEGER) RETURN NUMBER IS
NUM NUMBER;
BEGIN
SELECT COUNT(S.BODYMODELREF) INTO NUM FROM SINGLEDECKBUS_TABLE S WHERE S.BODYMODELREF.MODELID = thisModelID;
RETURN NUM;
END count_single_buses;
END;
/
Still not sure why #Ravi's exact code still produced the warning, and thought that resultset when returning a count value could go into an integer. At any rate, the code works now. Thanks all.
Your BodyModel2_Type Type definition looks okay. However, the body definition is syntactically incorrect.
You cannot define a SQL statement directly to a variable, thus making this statement wrong.
N := (SELECT COUNT(BODYMODELREF) FROM SINGLEDECKBUS_TABLE S
WHERE S.BODYMODELREF = ModelID);
You will have to use Select... into statement in order to assign the result set of your SQL query into a variable. So, the right syntax should look like this
SELECT COUNT(BODYMODELREF) FROM SINGLEDECKBUS_TABLE S INTO N
WHERE S.BODYMODELREF = ModelID
AFAIK you don't have END the Type followed by the Type name like this END count_single_buses. It'll produce an error. So, overall your Type body specification should look like this:
CREATE OR REPLACE TYPE BODY BodyModel2_Type AS
MEMBER FUNCTION count_single_buses(ModelID INTEGER) RETURN NUMBER IS
N NUMBER;
BEGIN
SELECT COUNT(BODYMODELREF) FROM SINGLEDECKBUS_TABLE S INTO N
WHERE S.BODYMODELREF = ModelID;
RETURN (N);
END;
END;
/
I'm writing this off without any live environment available right now so please let me know if you come across any error in the above code.
Cheers.

What is << some text >> in oracle

I found this character while reading some blog of pl sql << some text >> .
I found this character from following blog http://www.oracle-base.com/articles/8i/collections-8i.php
As others have said, <<some_text>> is a label named "some_text". Labels aren't often used in PL/SQL but can be helpful in a variety of contexts.
As an example, let's say you have several nested loops, execution has reached the very inner-most level, and the code needs to exit from all the nested loops and continue after the outer-most one. Here a label can be used in the following fashion:
<<outer_most_loop>>
LOOP
...
<<next_inner_loop>>
LOOP
...
<<inner_most_loop>>
LOOP
...
IF something <> something_else THEN
EXIT outer_most_loop;
END IF;
...
END LOOP inner_most_loop;
...
END LOOP next_inner_loop;
...
END LOOP outer_most_loop;
-- Execution continues here after EXIT outer_most_loop;
something := something_else;
...
Next, let's say that you've got some code with nested blocks, each of which declares a variable of the same name, so that you need to instruct the compiler about which of the same-named variables you intend to use. In this case you could use a label like this:
<<outer>>
DECLARE
nNumber NUMBER := 1;
BEGIN
<<inner>>
DECLARE
nNumber NUMBER := 2;
BEGIN
DBMS_OUTPUT.PUT_LINE('outer.nNumber=' || outer.nNumber);
DBMS_OUTPUT.PUT_LINE('inner.nNumber=' || inner.nNumber);
END inner;
END outer;
Labels can also be useful if you insist on giving a variable the same name as a column in a table. As an example, let's say that you have a table named PEOPLE with a non-nullable column named LASTNAME and you want to delete everyone with LASTNAME = 'JARVIS'. The following code:
DECLARE
lastname VARCHAR2(100) := 'JARVIS';
BEGIN
DELETE FROM PEOPLE
WHERE LASTNAME = lastname;
END;
will not do what you intended - instead, it will delete every row in the PEOPLE table. This occurs because in the case of potentially ambiguous names, PL/SQL will choose to use the column in the table instead of the local variable or parameter; thus, the above is interpreted as
DECLARE
lastname VARCHAR2(100) := 'JARVIS';
BEGIN
DELETE FROM PEOPLE p
WHERE p.LASTNAME = p.lastname;
END;
and boom! Every row in the table goes bye-bye. :-) A label can be used to qualify the variable name as follows:
<<outer>>
DECLARE
lastname VARCHAR2(100) := 'JARVIS';
BEGIN
DELETE FROM PEOPLE p
WHERE p.LASTNAME = outer.lastname;
END;
Execute this and only those people with LASTNAME = 'JARVIS' will vanish.
And yes - as someone else said, you can GOTO a label:
FUNCTION SOME_FUNC RETURN NUMBER
IS
SOMETHING NUMBER := 1;
SOMETHING_ELSE NUMBER := 42;
BEGIN
IF SOMETHING <> SOMETHING_ELSE THEN
GOTO HECK;
END IF;
RETURN 0;
<<HECK>>
RETURN -1;
END;
(Ewwwww! Code like that just feels so wrong..!)
Share and enjoy.
It's often used to label loops, cursors, etc.
You can use that label in goto statements. Else, it is just 'comment'.
Sample from Oracle:
DECLARE
p VARCHAR2(30);
n PLS_INTEGER := 37; -- test any integer > 2 for prime
BEGIN
FOR j in 2..ROUND(SQRT(n)) LOOP
IF n MOD j = 0 THEN -- test for prime
p := ' is not a prime number'; -- not a prime number
GOTO print_now; -- << here is the GOTO
END IF;
END LOOP;
p := ' is a prime number';
<<print_now>> -- << and it executes this
DBMS_OUTPUT.PUT_LINE(TO_CHAR(n) || p);
END;
/
It is a label, a subgroup of comments in the plsql syntax.
http://ss64.com/oraplsql/operators.html
Its is a label delimeter
<< label delimiter (begin)
label delimiter (end) >>
http://docs.oracle.com/cd/B10501_01/appdev.920/a96624/02_funds.htm

How to call Oracle MD5 hash function?

I have below code. I am using Oracle 11g.
SELECT DBMS_OBFUSCATION_TOOLKIT.md5 (input => UTL_RAW.cast_to_raw(
FIRST_NAME
||LAST_NAME
)) md5_key ,
FIRST_NAME ,
LAST_NAME
FROM C_NAME_TAB
WHERE PKEY='1234'
How can i call this code? Can i directly execute this code in sqldeveloper?
In Oracle 12c you can use the function STANDARD_HASH. It does not require any additional privileges.
select standard_hash('foo', 'MD5') from dual;
The dbms_obfuscation_toolkit is deprecated (see Note here). You can use DBMS_CRYPTO directly:
select rawtohex(
DBMS_CRYPTO.Hash (
UTL_I18N.STRING_TO_RAW ('foo', 'AL32UTF8'),
2)
) from dual;
Output:
ACBD18DB4CC2F85CEDEF654FCCC4A4D8
Add a lower function call if needed. More on DBMS_CRYPTO.
I would do:
select DBMS_CRYPTO.HASH(rawtohex('foo') ,2) from dual;
output:
DBMS_CRYPTO.HASH(RAWTOHEX('FOO'),2)
--------------------------------------------------------------------------------
ACBD18DB4CC2F85CEDEF654FCCC4A4D8
#user755806 I do not believe that your question was answered. I took your code but used the 'foo' example string, added a lower function and also found the length of the hash returned. In sqlplus or Oracle's sql developer Java database client you can use this to call the md5sum of a value. The column formats clean up the presentation.
column hash_key format a34;
column hash_key_len format 999999;
select dbms_obfuscation_toolkit.md5(
input => UTL_RAW.cast_to_raw('foo')) as hash_key,
length(dbms_obfuscation_toolkit.md5(
input => UTL_RAW.cast_to_raw('foo'))) as hash_key_len
from dual;
The result set
HASH_KEY HASH_KEY_LEN
---------------------------------- ------------
acbd18db4cc2f85cedef654fccc4a4d8 32
is the same value that is returned from a Linux md5sum command.
echo -n foo | md5sum
acbd18db4cc2f85cedef654fccc4a4d8 -
Yes you can call or execute the sql statement directly in sqlplus or sql developer. I tested the sql statement in both clients against 11g.
You can use any C, C#, Java or other programming language that can send a statement to the database. It is the database on the other end of the call that needs to be able to understand the sql statement. In the case of 11 g, the code will work.
#tbone provides an excellent warning about the deprecation of the dbms_obfuscation_toolkit. However, that does not mean your code is unusable in 12c. It will work but you will want to eventually switch to dbms_crypto package. dbms_crypto is not available in my version of 11g.
To calculate MD5 hash of CLOB content field with my desired encoding without implicitly recoding content to AL32UTF8, I've used this code:
create or replace function clob2blob(AClob CLOB) return BLOB is
Result BLOB;
o1 integer;
o2 integer;
c integer;
w integer;
begin
o1 := 1;
o2 := 1;
c := 0;
w := 0;
DBMS_LOB.CreateTemporary(Result, true);
DBMS_LOB.ConvertToBlob(Result, AClob, length(AClob), o1, o2, 0, c, w);
return(Result);
end clob2blob;
/
update my_table t set t.hash = (rawtohex(DBMS_CRYPTO.Hash(clob2blob(t.content),2)));