Why doesn't my alias show up in INFORMATION_SCHEMA.FUNCTION_ALIASES? - h2

I'm using H2 DB v1.4.182 for my test environment. It acts as a substitute in place of Oracle, which is the production vendor. I have a few aliases I create using a script in my test environment:
CREATE ALIAS IF NOT EXISTS REGEXP_LIKE as $$ boolean regexpLike(String s, String p) { return java.util.regex.Pattern.compile(p).matcher(s).find(); } $$;
CREATE ALIAS IF NOT EXISTS TO_NUMBER as $$ long toNumber(String s) { return Long.valueOf(s); } $$;
CREATE ALIAS if NOT EXISTS fn_val_check3 for "fakedata.testutil.TestUtil.fn_val_check";
The first two aliases show up in the INFORMATION_SCHEMA.FUNCTION_ALIASES table, the last one (fn_val_check3) doesn't.
SELECT ALIAS_NAME FROM INFORMATION_SCHEMA.FUNCTION_ALIASES;
Gives me two rows
ALIAS_NAME
TO_NUMBER
REGEXP_LIKE
I verified that H2 has the other alias somewhere by running the CREATE ALIAS ... directly in the console and it says
CREATE ALIAS fn_val_check3 for "fakedata.testutil.TestUtil.fn_val_check";
Function alias "FN_VAL_CHECK3" already exists; SQL statement: CREATE ALIAS fn_val_check3 for "fakedata.testutil.TestUtil.fn_val_check" [90076-182] 90076/90076 (Help)
I'm using a validation component to verify the function exists in the database, which is why I'm wondering. Am I missing something or is this a known thing?

Related

Can not create alias `IF` or `IFNULL`

I am trying to create an alias in H2database for IF and I get the following error.
org.h2.jdbc.JdbcSQLSyntaxErrorException: Function alias "IF" already exists; SQL statement:
CREATE ALIAS `IF` FOR "test.Udf.ifAlias" [90076-212]
Then I try to drop the IF before creating, and I get the following error.
org.h2.jdbc.JdbcSQLSyntaxErrorException: Function alias "IF" not found; SQL statement:
DROP ALIAS `IF` [90077-212]
Similar happens for IFNULL. I am trying the following lines in my init script.
DROP ALIAS `IF`;
CREATE ALIAS `IF` FOR "test.Udf.ifAlias";
And the Java function for the ifAlias is
public static boolean ifAlias(boolean condition, boolean exp1, boolean exp2) {
if(condition) {
return exp1;
}
return exp2;
}
Since version 1.4.198, IF is a keyword in h2. See this issue and responses: https://github.com/h2database/h2database/issues/3018

Reading and storing all files in directory using oracle procedure [duplicate]

I want to retrieve list of all file in a specific folder that included oracle form and menu and report and some txt file...
Do you have any idea how I can retrieve these data in ORACLE form, and insert them into my data block, automatically?
I use oracle form 6.0.
I did something along these lines:
Create an Oracle directory for the directory you want to list:
create or replace directory YOURDIR
as '\path\to\your\directory';
Build a temporary table:
create global temporary table DIR_LIST
(
FILENAME VARCHAR2(255),
)
on commit preserve rows;
grant select, insert, update, delete on DIR_LIST to PUBLIC;
You'll need a java stored procedure:
create or replace and compile java source named dirlist as
import java.io.*;
import java.sql.*;
import java.text.*;
public class DirList
{
public static void getList(String directory)
throws SQLException
{
File dir = new File( directory );
File[] files = dir.listFiles();
File theFile;
for(int i = 0; i < files.length; i++)
{
theFile = files[i];
#sql { INSERT INTO DIR_LIST (FILENAME)
VALUES (:theName };
}
}
}
And a PL/SQL callable procedure to invoke the java:
CREATE OR REPLACE PROCEDURE get_dir_list(pi_directory IN VARCHAR2)
AS LANGUAGE JAVA
name 'DirList.getList(java.lang.String)';
Finally, calling the procedure get_dir_list inside your form will populate the table with the files in your directory, which you can then read into your form block.
The java code came straight out of a Tom Kyte book (don't recall which one).
EDIT:
Actually, all the code is pretty much lifted from this AskTom thread.
There is another interesting approach with external tables that makes it even easier to retrieve such lists without using a Java stored procedure:
$ mkdir /tmp/incoming
$ cat >/tmp/incoming/readdir.sh<<eof
#/bin/bash
cd /tmp/incoming/
/bin/ls -1
eof
# test files
$ for i in {1..5}; do touch /tmp/incoming/invoice_no_$RANDOM.pdf; done
In SQL*Plus:
create or replace directory incoming as '/tmp/incoming';
Directory INCOMMING created.
create table files (filename varchar2(255))
organization external (
type oracle_loader
default directory incoming
access parameters (
records delimited by newline
preprocessor incoming:'readdir.sh'
fields terminated by "|" ldrtrim
)
location ('readdir.sh')
);
/
Table FILES created.
select * from files;
FILENAME
--------------------------------------------------------------------------------
FILES_27463.log
invoice_no_20891.pdf
invoice_no_2255.pdf
invoice_no_24086.pdf
invoice_no_30372.pdf
invoice_no_8340.pdf
readdir.sh
7 rows selected
This approach was added in the same Ask Tom thread as mentioned in the #DCookie's answere.

pg: exec_params not replacing parameters?

First time using pg gem to access postgres database. I've connected successfully and can run queries using #exec, but now building a simple query with #exec_params does not seem to be replacing parameters. I.e:
get '/databases/:db/tables/:table' do |db_name, table_name|
conn = connect(db_name)
query_result = conn.exec_params("SELECT * FROM $1;", [table_name])
end
results in #<PG::SyntaxError: ERROR: syntax error at or near "$1" LINE 1: SELECT * FROM $1; ^ >
This seems like such a simple example to get working - am I fundamentally misunderstanding how to use this method?
You can use placeholders for values, not for identifiers (such as table and column names). This is the one place where you're stuck using string interpolation to build your SQL. Of course, if you're using string wrangling for your SQL, you must be sure to properly quote/escape things; for identifiers, that means using quote_ident:
+ (Object) quote_ident(str)
Returns a string that is safe for inclusion in a SQL query as an identifier. Note: this is not a quote function for values, but for identifiers.
So you'd say something like:
table_name = conn.quote_ident(table_name)
query_result = conn.exec("SELECT * FROM #{table_name}")

Bash: Calling bash script from postgresql trigger function

I am calling a bash script from the trigger function in postgresql. The script is called after update of the value(log_interval) in the table in SQL.
The read the changed value(log_interval) from the table in the script that is called and store in a file (interval.txt). If I open the file I see the old value of log_interval and not the new value in the interval.txt file.
Below is the code snippet that I am using:
Trigger function:
CREATE OR REPLACE FUNCTION update_upload_interval()
RETURNS trigger AS
$BODY$
#!/bin/sh
exec /home/User/ReadInterval.sh &
$BODY$
LANGUAGE plsh VOLATILE
Trigger:
CREATE TRIGGER assign_new_interval
AFTER UPDATE OF log_interval
ON table_interval
FOR EACH ROW
WHEN ((old.log_interval IS DISTINCT FROM new.log_interval))
EXECUTE PROCEDURE update_upload_interval();
Script code:
function readinterval() {
logperiod=$(psql -c "select log_interval from table_interval where id=1;" -t $database_name)
echo "$logperiod" > /home/User/interval.txt
}
Am new to scripting and using SQL. Let me know the solution. Thanks in advance.
Unless there's more code that isn't being shown here, just calling ReadInterval.sh won't do anything because it's nothing but a function declaration. In addition, there's a variable $database_name that isn't being set.
CREATE OR REPLACE FUNCTION update_upload_interval()
RETURNS trigger AS
$BODY$
#!/bin/sh
database_name=???
psql -c "select log_interval from table_interval where id=1;" -t $database_name > /home/User/interval.txt
$BODY$
LANGUAGE plsh VOLATILE

Preventing sql injection with stored procedures

I'm calling a system stored procedure for full text search package. It generates terms used for full text search based on a sql literal.
ex: exec ctx_query.explain('index_name', 'full text filter', 'explain table') etc
I'm doing the following in my code:
using(OracleCommand command = new OracleCommand("ctx_query.explain", DataAccess.GetConnString()))
{
comm.Parameters.AddWithValue("index_name", "explain1");
//comm.Parameters.AddWithValue("text_query", "(test) OR (term1 ACCUM term2");
comm.Parameters.AddWithValue("text_query", txtUserInput.Text);
comm.Parameters.AddWithValue("explain_table", "explain_results");
comm.Parameters.AddWithValue("sharelevel", 0);
comm.Parameters.AddWithValue("explain_id", new Guid().ToString().Substring(0,30));
comm.ExecuteNonQuery();
}
The "text_query" parameter will be built from user input. Does the above prevent sql injection because the textUserInput.Text will be passed as a command parameter?
ctx_query.explain does not execute the query, it only examines it, so there is no SQL injection risk here.

Resources