Using Entity Framework and Oracle DB, I would like to
insert into tablename (datetimefield, numericfield) VALUES (sysdate, 545)
How to do that without using SQL code directly?
Its not possible to set it directly using the entity framework as part of the update. For inserts you coud set a default value on the table and leave it null. You could also expose an sp that updates the date to the entity framework, and call it, but that could cause many round trips.
You could also use a trigger.
If you work with dotConnect for Oracle, you can use this solution.
Devart Team
Related
I need a way to read/get data from a REST API to insert it into a table in Oracle DB.
I've been searching for it but I've only found the opposite case.
I'm using PL/SQL Developer & Postman
Do i need another software ?
Thanks.
If you want to use UTL_HTTP, you can do something as simple as an INSERT ... SELECT ...
INSERT INTO my_table(response_data)
SELECT utl_http.request('http://service.url.com')
FROM dual;
One way to go is with Oracle REST Data Services (ORDS).
It's a mid-tier Java application (or servlet with Tomcat/WebLogic) that takes HTTP(S) requests and marshalls that to the Oracle Database.
It handles GETs, PUTs, POSTs, & DELETEs so you can definitely use it to INSERT one or more rows to a TABLE. And it can do that via a SQL statement, or an existing PLSQL API.
I talk more about this here.
Here's a REST Service that let's you POST a new record to a TABLE, including a BLOB (file).
This technology is included with your Oracle Database license at no additional cost.
We are migrating our codebase from Delphi XE3 with FireDAC 8.0.5 to Delphi Berlin 10.1 Upd 2 with FireDAC 15.0.1 (Build 86746). Everything is working smoothly using MS Sql Server, but using ORACLE it has been another history.
Throughout the application source code we use lots of TAdQuery with sql instructions like
AdQuery1.Sql.Text := 'SELECT FIELD1, FIELD2 FROM TABLE1';
In order to insert a record, we use Append or Insert methods, like this
AdQuery1.Insert;
//or
AdQuery1.Append;
Just after invoking its Post method, the component internally creates an INSERT sql statement, that goes like this
INSERT INTO TABLE1 (FIELD1, FIELD2) VALUES(:FIELD1, :FIELD2)
So the record gets inserted successfully.
Now, using TFdQuery in Delphi Berlin, the component internally creates an INSERT sql statement, like this
INSERT INTO USERNAME.TABLE1 (FIELD1, FIELD2) VALUES(:FIELD1, :FIELD2)
Failing with a [FireDAC][Phys][Ora] ORA-00942: table or view does not exist
This happens because in our Oracle database, TABLE1 is created in a schema called MAIN_SCHEMA, and we access it by using a public synonym.
Trying to find a workaround, we compared FireDAC source code, finding that
in Delphi XE3, the unit uADDAptManager.pas, on its function TADDAptTableAdapter.GetUpdateRowCommand, calls oConn.CreateCommandGenerator(oCmdGen, nil);
in Delphi Berlin, the unit FireDAC.DApt.pas, on its function TFDDAptTableAdapter.GetUpdateRowCommand
calls oConn.CreateCommandGenerator(oCmdGen, GetSelectCommand);
Whenever that second parameter (called ACommand: IFDPhysCommand) is not nil, the name of the table is returned concatenating the user name (in a function called TFDPhysCommandGenerator.GetFrom).
If we add 'MetaCurSchema=MAIN_SCHEMA' to the TFdConnection params, it works with the applications that not use a pooled connection, but We have several process that use a pooled connection with the same params, even MetaCurSchema param, but it doesn't work
What can we do?
thanks for your help
What I understand is that you would do better making the connection avoid the use of any schema name, rather than specifying it. Also, keeping in mind that you already use public synonyms.
So, according to the documentation:
Full object names
FireDAC supports full object names, which include the catalog and/or schema names.
When a short object name is specified to StoredProcName, TableName, etc, they will be expanded into the full object names, using the current catalog and/or schema names. To override or avoid usage of the current catalog and/or schema names, use the MetaCurCatalog and MetaCurSchema connection definition parameters. For example:
[Oracle_Demo]
DriverID=Ora
...
MetaCurCatalog=*
MetaCurSchema=*
~ Source: Object Names (FireDAC) - docWiki
MetaCurSchema
Specifies the current schema for the application. If not specified, then its value will be received from the DBMS. When an application is asking for metadata and do not specify a schema name, then FireDAC will implicitly use the current schema.
If MetaCurSchema is '*', then schema names will be me omitted from the metadata parameters.
~ Source: Common Connection Parameters (FireDAC) - docWiki
That asterisk (*) should do the trick, let us know if that's the case.
I am using SimpleJdbcTemplate batchUpdate method to do batch inserts and updates. Currently since I do not know if it is an insert or update I query the database first. Is there a better way to do this ?
No - not really.
But an alternative scheme you might consider is to do like some banks: Do only INSERTs. Then you use proper SELECT statements to select only the most recent version of each row.
We have an application written in Delphi 2010 which connects to SQL Server Database. Now we're in the process of migrating to Oracle. With SQL Server it was very easy to perform insert, update, delete right from a dbgrid connected to a Stored Procedure.
It's because stored procedures in SQL Server can easily act as a table so that you can do any operation on it, providing it returns the necessary columns within the resultset. Now with Oracle I don't know how do do it. I connect a DBGrid to a DataSource, dataset of which is a Stored Procedure object,but I can't edit the grid. Just Select is possible.
What do I have to do to to achieve this?I use UniDac component suite to connect to Oracle database.
Oracle does not support such functionality. IOW, in Oracle you cannot edit result set provided by a stored procedure or include stored procedure into INSERT INTO <name>, UPDATE <name> or DELETE FROM <name>.
While it is traditional for SQL Server developers to "always" use stored procedures (due to many reasons), it is not traditional for Oracle developers. But it is possible with Oracle too. Search for "REF CURSOR" to see how to fetch data using SP. And use normal or packaged (preferred) SP to post updates to a DB. These procedure will receive old / new field values through arguments.
I cannot say precisely about UniDAC, I can say about AnyDAC. But I will expect UniDAC has similar functionality. To use SP for posting updates you will need to use TXxxUpdateSQL component.
OK,here I'm answering the question though I can see very few are dealing with Delphi recently. Let's say we have a stored proc in Oracle database:
CREATE OR REPLACE PROCEDURE GET_EMPLOYEES
(V_CUR IN OUT SYS_REFCURSOR)
AS
BEGIN
OPEN V_CUR FOR SELECT * FROM EMPLOYEES;
END GET_EMPLOYEES;
Now, in Delphi you pick a stored procedure component (probably from ODAC or UniDac component suite).Set its StoredProcName GET_EMPLOYEES. Then you can add all the fields that the procedure returns in a cursor.If you run the application and activate the stored procedure you'll be able to see all the records. But if you try to insert, modify or delete anything you'll fail to do so. Now, there's a very tricky thing. If you check, you'll see that ReadOnly property of all fields are set to True. Even after you set them to False nothing will change in the real database, although you can edit the DBGrid.
So, we've come to the main part. How did the old Delphi-SQL Server partnership work so that you could do any operation right from a DBGrid? Well, we must understand that there's no magic. If it's SQL, then SQL has only one way of INSERTING,UPDATING and DELETING records-it's with the appropriate SQL statements.With Delphi-SQL Server there seems to be an implicit SQL statement that we never paid attention. But with Oracle, we have to provide our own statements for each operation.
If you use UniDac or ODAC then there's SQLInsert,SQLUpdate,SQLDelete properties in a StoredProc object.If you want to insert a record through DBGrid, then you should edit its SQLInsert property to
INSERT INTO EMPLOYEES VALUES(:EMPLOYEEID,:EMPLOYEENAME)
where variables following : are corresponding to te fields of the stored procedure.They're simply bind variales.When updating and deleting though you'll need some unique value to represent a specific record. Primary key is one option(maybe the only option as I haven't been able to figure out how to use ROWID for the same purpose).So the sql statements for UPDATE and DELETE would be
DELETE FROM EMPLOYEES WHERE EMPLOYEEID=:EMPLOYEEID
and
UPDATE EMPLOYEES SET EMPLOYEENAME=:EMPLOYEENAME WHERE EMPLOYEEID=:EMPLOYEEID
P.S. I just found a way to use ROWID for update and delete statements. In your stored procedure if you choose ROWID too and give it an alias then you can construct your UPDATE and DELETE Statements like such:
UPDATE EMPLOYEES SET EMPLOYEENAME=:EMPLOYEENAME,..... WHERE ROWID=:RECORD_ROWID
DELETE FROM EMPLOYEES WHERE ROWID=:RECORD_ROWID
In the preceding statements RECORD_ROWID is the fieldname returned from stored procedure as a result of aliasing ROWID. If you use :ROWID instead you'll get "ORA-01745: invalid host/bind variable name" error. This is because in a binding variable a colon cannot be followed by a reserved word. And ROWID is a reserved word.
I think this question has been done before, but I don't find a clear answer.
I have migrated SQl Server 2005 database to oracle 11. I am using subsonic 2.1. I have manged to create all the data layer classes, and generates everything well. But the problem turns up when I try to make an insert in the database: Oracle does not have autoincrement in the primary key unless you define a sequence and a trigger. In consequence, Subsonic defines all the Insert methods in the controller with the id column. Is there a way to avoid subsonic not generate Insert methods with the id column, which I am going to generate using a trigger and a sequence?
Thanks a lot
SToledo
UPDATE
I finally did a horrible hack (I feel ashamed) in Subsonic 2.1 source code. I did modify OracleDataProvider to set id-named columns to be autoincrement to true. Then, the template will behave as I expect. I know is a terrible hack, but it works for me.
Thanks for your help guys.
Don't know about Subsonic, but if number of tables is relatively small, you can modify BEFORE-INSERT trigger to disable nullity check:
CREATE OR REPLACE TRIGGER trig_BI
BEFORE INSERT
ON tab_name
FOR EACH ROW
BEGIN
--IF :NEW.key_column IS NULL
--THEN
SELECT tab_seq.NEXTVAL INTO :NEW.key_column FROM DUAL;
--END IF;
END;