what is the code to create a table in sql only at first run of project? - sql

hello everyone,
I want to create a web application using jsp,servlet and jdbc etc.
It simply create a table of name student,contains various field as information about student in database and different page perform different query tasks .
The problem is that I want to create a war file to distribute this app to my client.
When I write a sql query to create a table in my jsp page , it tries to create a new table every time whenever I run this project.
Here i want that it creates a table only when the user run this first time.So that when I distribute the war file to my client ,on the first run it create a student name table and perform the required query and for the future run it only perform other query but not create a table again.
I need your valuable guidance and overview for solving this problem.Any type of help will be appreciated.
"thanks"

In Oracle, the workaround is to wrap it in an anonymous BEGIN-END block. The EXCEPTION block would simply allow the table already exists error.
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE...
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -955 THEN
NULL; -- ignore the ORA-00955 error
ELSE
RAISE;
END IF;
END;
/
This is one way preferably. Another way would be to manually check if the table exists or not in the data dictionary view dba_tables.
SELECT count(*)
INTO variable_count
FROM dba_tables
WHERE table_name = 'table_name';
So,
IF variable_count = 0 THEN EXECUTE IMMEDIATE CREATE TABLE ...

Related

Why is my initial SQL (Oracle) not accepted by Tableau?

For a project I've been working on, I had to create 2 tables in Oracle using Tableau's Initial SQL window. I basically need to re-create them each time Tableau does an extract, so would have to drop and re-create them. Only using the 'DROP' statement works, but if the extract fails in the middle of it, then when it re-runs, the tables don't exist, thus it returns an error.
I tried to use the below code which works fine in SQL Developer, but Tableau doesn't seem to accept it.
--Searches and deletes table TABLEAU_LCC_LEAD_TIME if it exists
DECLARE
does_not_exist EXCEPTION;
PRAGMA EXCEPTION_INIT (does_not_exist, -942);
BEGIN
EXECUTE IMMEDIATE 'DROP TABLE TABLEAU_DOC_LEAD_TIMES';
EXCEPTION
WHEN does_not_exist
THEN
NULL;
END;
/
Tableau returns this error
Would you know of any workaround for the "/" in Tableau Initial-SQL for Oracle?
I think use temporary table in Oracle. Not need re-created table. https://oracle-base.com/articles/misc/temporary-tables

Use new value in after trigger sql statement

I am trying to create a trigger that will dump out a csv file of data at a certain point in an application. When you create a payment order from a payment proposal then it means it is ready to be paid and uploaded to the bank. There is a wizard in the erp that makes the payment order from the payment proposal. There is also a header and a detail table on both proposals and orders. I need it to make it when there is a new row in the payment order table that has new.way_id = 'ACH' and new.institute_id = 'BMO'.
The problem is the wizard has multiple steps and doesn't insert the detail rows for the order till the last step when you click ok, but the header is created already before this and executes the trigger. Because of this when the header is created I am going to pull all of the data from the proposal header and detail because it is all already there.
When The trigger executes it makes a sql statement and then passes it to a stored procedure that will take any sql query and dump it to a csv file. For some reason it won't let me use the new reference when I create my query. I get an error saying "new.selected_proposals invalid identifier". I need it to do a like on this also because you can select multiple proposal header id's when you create an order and I only want it to do it for the ones from the proposals that have a way_id of ACH.
I am guessing I have to add the .new table, whatever it is, into the join or something, but I am not sure how to do that.
This is Oracle database 11g. Here is the code. The commented out section in the query is what I am trying to fix, just to give an idea of what I am trying to do.
create or replace TRIGGER CREATE_BMO_ACH_FILE
AFTER INSERT ON PAYMENT_ORDER_TAB
for each row
when (new.way_id = 'ACH' and new.institute_id = 'BMO')
declare sql_ varchar(4000);
BEGIN
sql_ := q'[select pp.company, pp.Proposal_id, pp.CREATION_DATE, pl.identity, pl.payee_identity, pl.ledger_item_id, pl.currency, pl.curr_amount, pl.GROSS_PAYMENT_AMOUNT, pl.PLANED_PAYMENT_DATE, pl.Order_Reference, pl.PAYMENT_REFERENCE
from payment_proposal pp, PROPOSAL_LEDGER_ITEM pl
where pp.company = pl.company
and pp.proposal_id = pl.proposal_id
and pp.way_id = 'ACH'
/*and pp.proposal_id like '%' || new.selected_proposals || '%'*/]';
dump_sql_to_csv( sql_, 'E:\Accounting', 'test.csv');
END;
I think your just missing a colon in front of the new i.e. use :new.selected_proposals. Colons aren't required for old and new in the WHEN but are in the code block.

Umbraco + Petapoco - Stored procedure to temp table

Evening,
I'm trying to exec a stored procedure into a temporary table so I can join some bits from another table.
Obviously the ideal solution would be to add the join into the stored procedure however this is currently not an option.
Here's what I'm trying to run in my controller action:
db.Query<HomeLatestTradesViewModel>(Sql.Builder
.Append("INSERT INTO #tmp_trade")
.Append("EXEC get_trade_data_latest")
);
Which hits me with:
Invalid object name 'HomeLatestTradesViewModel'.
I believe this is because I need a ; before the EXEC however that just throws an error telling me it shouldn't be there!
Any help getting this to work is appreciated.
If you want to execute (not retrieve data), you should use
db.Execute(Sql.Builder
.Append(";INSERT INTO #tmp_trade")
.Append("EXEC get_trade_data_latest")
);
(but I guess this wont work, depends on how have you create the temp table, and if you are in a transaction)
If you want to fiddle with temp data, you are better getting the data into a list, and then playing with it
var templist = db.Query<HomeLatestTradesViewModel>(Sql.Builder
.Append("EXEC get_trade_data_latest")
);

How to demonstrate SQL injection in where clause?

I want to demonstrate the insecurity of some webservices that we have. These send unsanitized user input to an Oracle database Select statements.
SQL injection on SELECT statements is possible (through the WHERE clause), however I am having a hard time to demonstrate it as the same parameter gets placed in other queries as well during the same webservice call.
E.g:
' or client_id = 999'--
will exploit the first query but as the same WS request calls runs other SQL SELECTs, it will return an oracle error on the next query because the client_id is referred to by an alias in the second table.
I am looking to find something more convincing rather than just having an ORA error returned such as managing to drop a table in the process. However I do not think this is possible from a Select statement.
Any ideas how I can cause some data to change, or maybe get sensitive data to be included as part of an ORA error?
It's not very easy to change data, but it's still possible. Function that created with pragma autonomous_transaction can contain dml and may be called in where. For instance,
CREATE OR REPLACE FUNCTION test_funct return int
IS
pragma autonomous_transaction;
BEGIN
DELETE FROM test_del;
commit;
return 0;
end;
-- and then
SELECT null from dual where test_funct()=1;
Another option you try creating huge subquery in WHERE which in turn may cause huge performance issue on server.
You do not need a custom function, you can use a sub-query:
" or client_id = (SELECT 999 FROM secret_table WHERE username = 'Admin' AND password_hash = '0123456789ABCD')"
If the query succeeds then you know that:
There is a table called secret_table that can be seen by the user executing this query (even if there is not a user interface that would typically be used to directly interact with that table);
That it has the columns username and password_hash;
That there is a user called Admin; and
That the admin user has a password that hashes to 0123456789ABCD.
You can repeat this and map the structure of the entire database and check for any values in the database.

How to count how many sql statements are there in an SQL file?

So, given an SQL file to be executed in Oracle, we are asked to determine how many blocks are to be executed within the SQL file. For example, there is one block in an SQL file containing the following command,
CREATE TABLE customer (id varchar2(42));
two blocks in the following SQL file,
ALTER TABLE customer ADD name varchar2(42);
ALTER TABLE customer DROP COLUMN id;
and three blocks in the following SQL file
CREATE OR REPLACE PROCEDURE printHelloWorld IS
BEGIN
dbms_output.put_line('Hello World!');
END;
/
INSERT INTO customer VALUES ('ivan');
DROP TABLE customer;
We can't assume anything else about the input, other than the fact it will be executed without any error in Oracle SQLDeveloper.
UPDATE
The purpose of asking the question is to ensure that there would only be one statement, which is to be executed, in the SQL file. I am also open to the answer of this question. It would be even better to be able to create a script to split a multiple-statement SQL file to multiple files.
Not a perfect solution but will work in most cases I think.
First create a duff user with no rights except to create a session.
CREATE USER duff IDENTIFIED BY "password";
GRANT CREATE SESSION TO duff;
Then use this with sqlplus and grep to count the ORA- errors - should be one per statement.
sqlplus duff/password#db < script.sql | grep -c ORA-
If you have ALTER SESSION statements then you need a bit more
sqlplus duff/password#db < script.sql | grep -Ec 'ORA-|Session altered.'
There maybe other exceptions, but I think it gives you a workable solution for little overhead. Be careful that scripts don't switch user - but if you have hard-coded usernames and passwords in your scripts you have other issues.