Oracle PL/SQL get the first letter from the name(HUN) - oracle

The question sounds easy because only need a substring (name,1,1). But in the Hungarian language there are many letter wich contains multicharacter. eg : CS,DZ,DZS,LY,NY,SZ,TY,ZS
IF v_type='by_name' THEN
select DISTINCT name
into v_result
from my_table
where instr(_START_LETTERS_,substr(upper(v_name),1,1))>0 and ZIPCODE = v_act_zipcode;
return v_result;
and my table eg:
zipcode name _START_LETTERS
1234 Ryan A,B,C
1234 Bryan CS,D
And if i want to get my name CSanád i need to get CS not the first char C-> becuase i will get multirow exception.
Do you have anysuggestion to use get the first lettor? Or I have to write a huge if-else/case structure to make my code awful and impenetrable.
Thanks

I think the most straight-forward solution is to write a stored function that extracts the first letter:
create function hun_first_letter(name in varchar2) return varchar2 as
begin
if substr(upper(name),1,3) in ('DZS') then
return substr(name,1,3);
elsif substr(upper(name),1,2) in ('CS','DZ','LY','NY','SZ','TY','ZS','GY') then
return substr(name,1,2);
else
return substr(name,1,1);
end if;
end;

Try to replace substr(upper(v_name), 1, 1) with:
regexp_substr(upper(v_name), '^[[:alpha:][.cs.][.xx.][.yy.]]', 1, 1, 'i')
where
[:alpha:] is a special function (any letter) - actually, I don't know, maybe this function alone can find collating sequences (depending on NLS)
[.cs.] is an example of a collating sequence;
[.xx.], [.yy.] - other collating sequences possible in your NLS
So the regexp_substr above tries to find any letter OR 'cs' OR 'xx' OR 'yy' and etc.
It starts searching from position = 1 and returns occurance = 1. Finally, the search is case insentitive ('i')
But first of all you may check whether this function:
regexp_substr(upper(v_name), '^[[:alpha:]]', 1, 1, 'i')
would find your collating sequences (I'd be glad to know this)

Related

Oracle Apex Checkbox Group Limit

This might be a silly one but haven't been able to figure it out.
I have a Checkbox Group Item (with Static info) with 4 different options, I want to limit the amount of checked boxes to just two. Is this something possible to make?
Thank you
A checkbox is submitted as a colon-separated string. APEX_STRING has lots of functionality to convert the string to a pl/sql collection (and back). Once converted you can use functions like FIRST, LAST, COUNT. Or even compare collections using INTERSECT. For checking a max nr, a COUNT is enough.
So the validation would be something like this (type Function Body returning Error Text):
DECLARE
l_arr apex_t_varchar2;
BEGIN
l_arr := apex_string.split(:P13_CHECKBOX,':');
IF l_arr.COUNT > 2 THEN
RETURN 'Can only select 2 values';
ELSE
RETURN NULL;
END IF;
END;

Case within a Select returning "missing expression ORA-00905"

this is my first post here, I'd like to ask for help on a theoretically simple query.
The current query I'm creating is to try and generate a random number, which will be identified as even or odd. Depending on that value, it should print either "M" as even, or "W" as odd. Though when I try using a case inside the select, I'm getting the "missing keyword" error. This is my following code:
select
case
when mod(round(dbms_random.value(1,100)),2) = 0 then dbms_output.put_line('M');
when mod(round(dbms_random.value(1,100)),2) = 1 then dbms_output.put_line('W');
end
from dual
I've tried checking the website for similar problems, and while I've found similar problems and people getting the solution correctly, I don't quite know what I'm missing here. When I run the select alone, I get the even or odd number I want to get, but not when I try to print out a result.
SELECT statement cannot PRINT, it can only RETURN something.
You may use query like
select
v,
case when mod(v, 2) = 0 then 'M' else 'W' end l
from
(select round(dbms_random.value(1, 100)) v from dual)
and process it's result as you wish (print, for example).
Why are you trying to embed dbms_output in a query? Just write:
select
case
when mod(round(dbms_random.value(1,100)),2) = 0 then 'M'
when mod(round(dbms_random.value(1,100)),2) = 1 then 'W'
end
from dual
Also you know, since you are calling dbms_random two different times, you get two different values in the same query. If you want one value to be compared, then use a WITH clause
with rand_value as
( select round(dbms_random.value(1,100)) val from dual
)
select
case
when mod(val,2) = 0 then 'M'
when mod(val,2) = 1 then 'W'
end
from rand_value
You get the error because of the semicolons.
Also you are calling the random function twice and thus get two different random values. I would use IF-THEN-ELSE instead of a SELECT statement, since the latter one cannot print.
IF mod(round(dbms_random.value(1,100)),2) = 0 THEN
dbms_output.put_line('M');
ELSE
dbms_output.put_line('W');
END IF;

Inferring type of values returned by the SQLite3 shell tool

I am out of necessity using the SQLite3 shell tool to maintain a small database. I'm using -header -ascii flags, although this applies—as far as I can tell—to any of the output choices. I'm looking a way to avoid ambiguity over the type of any one value returned. Consider the following:
Create Table `things` (`number` Integer, `string` Text, `binary` Blob);
Insert Into `things` (`number`,`string`,`binary`) Values (4,'4',X'34');
Select * From `things`;
This returns (using caret notation):
number^_string^_binary^^4^_4^_4^^
As is evident, there is no way to infer the type of any of the '4' characters from the response alone as none of them have distinguishing delimiters.
Is there any way to coerce the inclusion of type metadata into the response?
I'd like to avoid:
Altering query statements to also include types as that would be obfuscatory and would be superfluous in the event I did switch interfaces;
Prefixing TEXT and BLOB values prior to insert as this would have to be uniform for all TEXT and BLOB interaction (in saying that, this is still my preferred choice should it come to that).
What I'm looking for is a switch of some kind that indicates type as part of SQLite's response, e.g.:
number^_string^_binary^^4^_'4'^_X'4'^^
number^_string^_binary^^4^_text:4'^blob:4^^
Or some variation thereof. Fundamental to this is the response alone contains enough information to discern the type and value of each element of that response (much in the same way sqlite3_column_type() allows in the SQLite Library API).
Update: I've refined this question since the first answer by #mike-sherrill-cat-recall to clarify expectations.
In SQLite, it doesn't always make sense to echo the data type of a column. SQLite doesn't have column-wise data types in the traditional sense. You can use typeof(X) in SQL to show the "datatype of the expression X".
sqlite> create table test (n integer, d decimal(8, 2));
sqlite> insert into test (n, d) values (8, 3.14);
sqlite> insert into test (n, d) values ('wibble', 'wibble');
Inserting text into an integer column succeeds.
sqlite> select n, typeof(n), d, typeof(d) from test;
n typeof(n) d typeof(d)
---------- ---------- ---------- ----------
8 integer 3.14 real
wibble text wibble text
You can concatenate anything you like--even producing caret notation--but it's kind of clumsy.
sqlite> select '(' || typeof(n) || ')^_' || n as caret_n from test;
caret_n
-------------------------
(integer)^_8
(text)^_wibble
SQLite Core Functions
The shell always converts printed values to strings. (That's what "print" means.)
If you don't want to add separate output columns for the types, you could use the quote function to output all values according to SQL syntax rules:
sqlite> with v(x) as (values (null), (1), (2.3), ('hello'), (x'00')) select quote(x) from v;
NULL
1
2.3
'hello'
X'00'

Mismtach Error in Foxpro SQL insertion

I need someone could help me out on how to trace the error of "mismatched data type" in visual foxpro 6.0 When I issues a command like this "insert into tmpcur from memvar".
tmpcur is a cursor having bulk numbers of columns and it is ready hard to trace which one is having mismatch in data type for insertion problem.
It is pretty difficult to trace the insertion loop of each record into VFP tables one by one unliked MSSQL profiler.
Appreciate to someone could help. Thanks.
This should help you. I have a temp cursor created with some bogus field / column names testing for types of character, integer, double, currency, date and time. Trying to follow what is the result of your scenario, I am taking the memory variable of "bbbb" which should be double (or numeric at the least), and changed it to a string.
I am then HOLDING the error trapping routine that MAY be in effect, then setting my own (as I don't think try/catch existed in VFP6.. it may, but I just don't remember. So, I did an ON ERROR, set a variable to true. Then, I default it to false, try the insert, then check the flag. If the flag IS set, then I go into a loop and try for each column in the given table/alias (in my example it is "C_Tmp", so replace with your table/alias). It goes through each variable, and if the data type is different from the table structure, it will dump the column name and table / memory value for you to review.
You could put this to a log file or something.
Now, another consideration. Some types are completely valid and common for implied conversion, such as character and memo fields can both get strings. Integer, double, float, currency can all work with generic "numeric" values.
So, if you encounter these differences, then we can go one level further and look for comparable types, but let me know and we can adjust as needed.
At least this should give you a huge jump to your insert issue.
CREATE CURSOR C_tmp ( cccc c(10), iiii i, bbbb b(2), ccyyyy y, ddd d, tttt t )
SCATTER MEMVAR memo
m.bbbb = "wrong data type, was double with 2 decimal"
lcHoldError = ON("ERROR")
ON ERROR lFailInsert = .t.
lFailInsert = .f.
INSERT INTO C_Tmp FROM memvar
IF lFailInsert
FOR lnI = 1 TO FCOUNT( "C_Tmp" )
lcTmp = FIELD( lnI, "C_Tmp" )
IF NOT TYPE( "C_Tmp." + lcTmp ) == TYPE( "m.&lcTmp" )
? "Invalid " + lcTmp + ", C_Tmp.&lcTmp, m.&lcTmp
ENDIF
ENDFOR
ENDIF
ON ERROR &lcHoldError

Free Pascal - Problem solving query (not syntax) - how to approach the next phase of this loop

I have more of a 'problem solving' question than a syntax related problem.
Briefly, I'm creating a program that will read a text file full of words (that may feasibly be a list of passwords), one word per line - I'll be using ReadLn for that bit in a loop. For every word it finds, I want it to add "an amount" of obfuscation in line with how users these days will use '3' instead of 'E' in their passwords, or '1' instead of 'I'. I work in the IT security field and password breaking is often part of it and that's what the program is for.
I have managed to create the program so far that it generates a LEET table full of many different values for each letter of the alphabet and stacks them in a StringGrid that I can access as part of the process (and it is also outputted visually to a table).
type
TLetters = 'A'..'Z';
TLeet = array[TLetters] of TStringList;
var
SourceFileName, str : string;
StartIndexFile : TextFile;
i : TLetters;
leet : TLeet;
s : string;
n, o, ColumnSize : integer;
begin
for i in TLetters do
leet[ i ] := TStringList.Create;
// The next sequence of loops populates the string grid by counting the number of characters for each letter of the alphabet and then inserting them down, column by column and row by row...
//Letter A:
s := '4 # /-\ /\ ^ aye ∂ ci λ Z';
ColumnSize := wordcount(s,[' ']);
o := 0;
for n := 0 to ColumnSize do
leet['A'].Add(ExtractWord(n,s,[' ']));
for o := 0 to ColumnSize do
StringGrid1.Cells[1,o] := Leet['A'][o];
// And so on for B - Z
// ... then an OpenDialog that opens the source text file to read. Got that sorted
// A load of file opening stuff and then the obsfucation
repeat
Readln(StartIndexFile, Str);
LblProgress.Caption := ('Parsing Index File...please wait');
OBSFUCATE THE WORDS HERE TO SOME EXTENT
// but now I have hit a barrier....
until(EOF(StartIndexFile));
My problem is this : given the word 'Edward', for example, how do I decide to what level I should obfuscate it? Just the first letter 'E' to be replaced with a '3', and nothing more perhaps? Or the first two letters 'E' and 'd' to be replaced with ALL the values in the LEET table for both of the letters E and d (meaning dozens of new words would be generated from 'Edward', and so on), or all the values for 'E' but nothing else...the list goes on. Potentially, for every word, I could create thousands of additional one's! A 100Gb source file would soon become terabytes!
In other words, I need to set "a level" for which the program will function, that the user can decide. But I'm not sure how to structure that level?
So I'm not sure how to make it work? I didn't really think it through enough before I started. My initial thoughts were "It would be cool to have a program that would take an index of words from a computer, and then generate variations of every word to account for people who obfuscate characters." but having come to code it, I've realised it's a bigger job than I thought and I am now stuck at the section for actually 'LEETing my input file'!
You could use a level (0-10) as input.
0: replace nothing
10: replace all letters with LEET letters.
Depending on the length of the word, you calculate how many letters to replace and just replace random letters in the word, so that you not always replace the first letter for level 1 etc.

Resources