Netcool/OMNIbus SQL procedure not running\doing nothing - sql

So i have a tool that call procedure.
Tool looks like that:
call Attach_test('select TTID from alerts.status where Class in (73000,8891) and to_int(TTID) > 0 and ServerSerial in ($selected_rows.Serial)',[ $selected_rows.Serial ]); flush iduc;
it should get TTID (that field have only one of many selected alarms ) and array of server serials of selected alarms.
Then all this data is transfered to SQL procedure that looks like:
declare
tempservser integer; k integer;
begin
for k = 1 to array_len(serserial) do
begin
set tempservser = serserial[k];
update alerts.status set ParentTT = parentttid, TTFlag = 2 where ServerSerial = tempservser and TTID = '' ;
end;
end
Parameters:
in parentttid Char(11)
in serserial array of Integer
And here comes the trouble - procedure do nothing. There is no errors or something but there is no update on selected alarms.
I want it to work like this - you select many alarms with only one that have TTID, run this tool that set ParentTT = TTID on every other of selected alarms.
OS ver. 8.1
Sorry for my english

I figured out how to do it:
Tool
call AttachSelectedToTTID([ $selected_rows.Serial ],[ $selected_rows.ParentTT ]);
flush iduc;
Procedure
declare
tempservser integer; k integer;n integer;partt char(15);
begin
for n = 1 to array_len(ttid) do
begin
if (ttid[n] != '' ) then
set partt = ttid[n];
end if;
end;
for k = 1 to array_len(serserial) do
begin
set tempservser = serserial[k];
update alerts.status set ParentTT = partt,TTFlag = 2 where Serial = tempservser and TTID = '';
end;
end
Parameters:
in ttid array of Char(15)
in serserial array of Integer

Related

how to generate a readable name in a SQL stored procedure?

In a stored procedure, I would like to generate a 'name' field in order to populate a dummy data table.
I use this and it works:
SET #nom = CONV(FLOOR(RAND() * 99999999999999), 20, 36);
But since this is for a name field, I would like to have only letters and not a mixture of letters and numbers.
I wanted to try something like this, but it doesn't work
SET #lenght=8+rand() *10; -- Définit une longueur aléatoire compris entre 8 et 18 caractères
SET#nom='';
WHILE #lenght>0 DO
#nom = CONCAT(#nom, char(round(rand()*25+65,0)));
SET #lenght=#lenght -1;
END WHILE;
do you have an idea?
Array-type variables cannot be used?
I could have taken a random character in an array variable on each iteration of the loop
SET #vowel= ('a','e','i', 'o','u','y');
For MySQL:
CREATE FUNCTION generate_random_word (len TINYINT UNSIGNED)
RETURNS VARCHAR(255)
BEGIN
DECLARE result VARCHAR(255) DEFAULT '';
REPEAT
SET result = CONCAT(result, CHAR(CEIL(RAND()*26+64)));
SET len = len - 1;
UNTIL !len END REPEAT;
RETURN result;
END
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=e2732456d0d418b1b181a4352c534119

Using levenshtein on parts of string in SQL

I am trying to figure out a way to work some fuzzy searching methods into our store front search field using the Levenshtein method, but I'm running into a problem with how to search for only part of product names.
For example, a customer searches for scisors, but we have a product called electric scissor. Using the Levenshtein method levenshtein("scisors","electric scissor") we will get a result of 11, because the electric part will be counted as a difference.
What I am looking for is a way for it to look at substrings of the product name, so it would compare it to levenshtein("scisors","electric") and then also levenshtein("scisors","scissor") to see that we can get a result of only 2 in that second substring, and thus show that product as part of their search result.
Non-working example to give you an idea of what I'm after:
SELECT * FROM products p WHERE levenshtein("scisors", p.name) < 5
Question: Is there a way to write an SQL statement that handles checking for parts of the string? Would I need to create more functions in my database to be able to handle it perhaps or modify my existing function, and if so, what would it look like?
I am currently using this implementation of the levenshtein method:
//levenshtein(s1 as VARCHAR(255), s2 as VARCHAR(255))
//returns int
BEGIN
DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
DECLARE s1_char CHAR;
-- max strlen=255
DECLARE cv0, cv1 VARBINARY(256);
SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
IF s1 = s2 THEN
RETURN 0;
ELSEIF s1_len = 0 THEN
RETURN s2_len;
ELSEIF s2_len = 0 THEN
RETURN s1_len;
ELSE
WHILE j <= s2_len DO
SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
END WHILE;
WHILE i <= s1_len DO
SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
WHILE j <= s2_len DO
SET c = c + 1;
IF s1_char = SUBSTRING(s2, j, 1) THEN
SET cost = 0; ELSE SET cost = 1;
END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
IF c > c_temp THEN SET c = c_temp; END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
IF c > c_temp THEN
SET c = c_temp;
END IF;
SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
END WHILE;
SET cv1 = cv0, i = i + 1;
END WHILE;
END IF;
RETURN c;
END
This is a bit long for a comment.
First, I would suggest using a full-text search with a synonyms list. That said, you might have users with really bad spelling abilities, so the synonyms list might be difficult to maintain.
If you use Levenshtein distance, then I suggest doing it on a per word basis. For each word in the user's input, calculate the closest word in the name field. Then add these together to get the best match.
In your example, you would have these comparisons:
levenshtein('scisors', 'electric')
levenshtein('scisors', 'scissor')
The minimum would be the second. If the user types multiple words, such as 'electrk scisors', then you would be doing
levenshtein('electrk', 'electric') <-- minimum
levenshtein('electrk', 'scissor')
levenshtein('scisors', 'electric')
levenshtein('scisors', 'scissor') <-- minimum
This is likely to be an intuitive way to approach the search.

Incorrect Syntax; Access VBA function to SQL Server

I am converting a large MS Access application to run almost entirely on SQL Server to increase performance as the Access DB is ancient and extremely slow. As such I am working on recreating the VBA functions into SQL functions. SQL Server is giving me syntax errors all over the place and I am trying to understand why, here is the VBA:
Function AlphaNum(prodno As String)
Dim i As Long
If Len(prodno) = 0 Then Exit Function
For i = 1 To Len(prodno)
If Mid(prodno, i, 1) Like "[0-9a-z]" Then AlphaNum = AlphaNum & Mid(prodno, i, 1)
Next i
If IsNumeric(AlphaNum) Then
While Left(AlphaNum, 1) = "0"
AlphaNum = Mid(AlphaNum, 2)
Wend
End If
End Function
I've gotten this far with SQL.. I am certainly not an expert at this either, any ideas?
CREATE FUNCTION dbo.[NAL_AlphaNum]
(
#prodno varchar(10)
)
RETURNS VarChar(10)
BEGIN
DECLARE #counter INT,
#AlphaNum varchar(10)
SET #counter='1'
CASE WHEN Len(#prodno) = 0 THEN EXIT
WHILE #counter < Len(#prodno)
BEGIN
CASE WHEN Mid(#prodno, i, 1) LIKE '[0-9a-z]'
THEN #AlphaNum = #AlphaNum + Mid(#prodno, i, 1)
SET #counter = #counter + 1
END
CASE WHEN IsNumeric(#AlphaNum) THEN
WHILE Left(#AlphaNum, 1) = '0'
#AlphaNum = Mid(#AlphaNum, 2)
END
RETURN #AlphaNum
END;
Thank you in advance.

IBM Informix aggregate function

I need to develop some kind of function in a informix db, in order to split one string into multiple rows for example:
Column1
one,two,three,four
And my expected result is:
column1
one
two
three
four
What i was thinking is to create a function, that splits the string into multiple rows. My actual code is the next one :
create function split(text_splitted varchar(100), separator char(1))
returning varchar(100)
define splitted_word varchar(100);
define current_val char(1);
define start, cont integer;
let start = 0;
let splitted_word = "";
let current_val = "";
for cont = 0 to length(text_splitted)
let current_val = substr(text_splitted, cont, 1);
if current_val = separator then
let splitted_word = substr(text_splitted, start, cont - start);
let start = cont + 1;
return splitted_word with resume;
end if;
end for;
end function
If you execute the next statement, works find:
execute function split('hello.my.name.is', '.');
And the result is:
hello
my
name
this is perfect, but my problem is that when you launch a query with this function, and the function returns more than one row an error is raised. What i have been google, is that i need to create an aggregate function but i am not able to build this function. I am new in this kind of developing....
Here is the little documentation i found: http://www.pacs.tju.edu/informix/answers/english/docs/dbdk/is40/extend/04aggs3.html
Thanks!

How to call procedure with package type param in oracle?

In oracle DB, I created a custom type in a package and i guess this type is similar to integer array.
create or replace PACKAGE mypackage AS
TYPE custom1 is table of integer index by binary_integer;
END mypackage;
Used type in procedure IN param and expecting out param to be size of IN param.
CREATE OR REPLACE PROCEDURE MYPROCEDURE( param1 in mypackage.custom1, count1 out integer) IS
begin
count1 := param.count();
END MYPROCEDURE
Now I want to call above procedure,for this I should prepare mypackage.custom1.
Please help me in constructing mypackage.custom1 and call above procedure.
You have some errors in your code;
CREATE OR REPLACE PACKAGE mypackage AS
TYPE custom1 IS TABLE OF INTEGER
INDEX BY BINARY_INTEGER;
END mypackage;
CREATE OR REPLACE PROCEDURE MYPROCEDURE(param1 IN mypackage.custom1, count1 OUT INTEGER) IS
BEGIN
count1 := param1.COUNT();
END MYPROCEDURE;
To call your procedure, you simply need to define two variables and call the procedure with them; for example, in an anonymous block:
declare
v mypackage.custom1;
n number;
begin
select 1
bulk collect into v
from dual connect by level <= 5;
--
MYPROCEDURE(v, n);
dbms_output.put_line('n= ' || n);
end;
n= 5
The same way, you can build your stored procedures, packages, ... to call your procedure.
Executing above procedure with list of integers passing to custom type
SET SERVEROUTPUT = ON;
declare
v mypackage.custom1;
n number;
begin
v(0) := 10;
v(1) := 12;
v(2) := 14;
v(3) := 16;
--
MYPROCEDURE(v, n);
dbms_output.put_line('n= ' || n);
end;
output :
n = 4
Here is the JDBC code to invoke above procedure
String procedure = "call MYPROCEDURE(?, ?)";
CallableStatement callableStatement = con.prepareCall(procedure);
ArrayDescriptor ad = ArrayDescriptor.createDescriptor("mypackage.custom1", con);
ARRAY arr = new ARRAY(ad, con, new Integer[]{1,2,3,4});
callableStatement.setArray(1, arr);
callableStatement.registerOutParameter(2, Types.INTEGER);
final boolean execute = callableStatement.execute();
System.out.println("No of entries :" + callableStatement.getObject(2));
output :
No of entries : 4