Doctrine 2 Symfony 5 migration to an oracle database - oracle

I have
PHP 8.0
Ubuntu 20.4 running in a VM
Symfony Version 5
doctrine/orm 2.8.2
doctrine/dbal 2.12.1
doctrine/migrations 3.1.1
and oracle19c running
I have also some entities which I want now to make:migrate with doctrine. But at this point I stuck on this error:
More information:
In doctrine.yaml:
dbal:
default_connection: oracle
connections:
default:
schema_filter: ~^(?!t_cmdb_|m_cmdb_|migration_versions)~
mapping_types:
enum: string
# configure these for your database server
url: '%env(resolve:DATABASE_URL)%'
driver: 'pdo_mysql'
server_version: '5.7'
charset: utf8mb4
oracle:
schema_filter: ~^(?!t_cmdb_|m_cmdb_|migration_versions)~
mapping_types:
enum: string
# configure these for your database server
url: '%env(resolve:DATABASE_CUSTOMER_URL)%'
servicename: 'pdb'
service: true
driver: 'oci8'
server_version: ~
charset: AL32UTF8
I have a oracle database created with:
php bin/console doctrine:database:create --connection oracle
which goes through without any problems
Than I call
php bin/console make:migration -vvv
I got this error message:
[Doctrine\DBAL\Exception]
Unknown database type interval day(3) to second(2) requested, Doctrine\DBAL\Platforms\OraclePlatform may not support it.
All my date columns have the type datetime there is no interval in there!
I have searched for this problem but I can't come through.
Did somebody has this Problem while making migration for doctrine?
Thanks a lot for any hint.
Michael

Doctrine commands usually scan all tables in the user/schema defined in Symfony's .env file (look for DATABASE_USER). That error means that at least one of the tables in that schema has a column of type "INTERVAL...".
If you are sure that you don't have any table with an "INTERVAL..." type column, it may be that you are using directly the SYSTEM user/schema (or any other Oracle reserved user/schema). In this case, you need to create a separate user/schema for your project and move your project tables there.
Anyway, run this to check which tables under which user/schema (OWNER) have a column of type "INTERVAL...":
SELECT
OWNER,
TABLE_NAME ,
COLUMN_NAME,
DATA_TYPE,
DATA_LENGTH,
DATA_PRECISION,
DATA_SCALE
FROM ALL_TAB_COLUMNS
where
data_type like 'INTERVAL%'
-- and OWNER = 'YOUR_USER_SCHEMA' -- must be in uppercase
ORDER BY TABLE_NAME
If you do use such a column type in your project, then you must add that column type in Doctrine's configuration: https://www.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/custom-mapping-types.html
If you discover that you were using the SYSTEM user/schema directly (perhaps in a Docker container?), then create your separate project user/schema:
CREATE USER your_separate_user_schema IDENTIFIED BY oracle; -- oracle is the password
Grant create session to your_separate_user_schema ; -- to be able to login with the new user
ALTER USER your_separate_user_schema quota unlimited on USERS; -- give your user schema disk space
To copy only the necessary tables from SYSTEM to your_separate_user_schema: while in system/sysdba, for each table do:
create table your_separate_user_schema.table_name as select * from table_name ;

Related

Informix - select from a table of another user

I have to do CRUD operations on a table that is not owned by the user I am using to connect to my Informix database. I have been granted the necessary privileges to do the operations, but I do not know how to do the actual query.
I have little experience with Informix, but I remember in OracleDB I had to do reference the shema like so:
SELECT * FROM SCHEMA.TABLE;
In Informix should I reference the user that owns the table ? Like :
SELECT * FROM OWNER:TABLE
Or can I just do :
SELECT * FROM TABLE
Thanks for any help !
In Informix you can generally use the table name without or without the owner prefix unless the database was created with mode ANSI in which case the owner prefix is required. Note that the correct syntax when using the owner is to use a period "." as in:
SELECT * FROM owner.table;
The colon is used to separate the database name as shown in the Informix Guide to SQL: Syntax https://www.ibm.com/docs/en/informix-servers/14.10?topic=segments-database-object-name#ids_sqs_1649
FYI you can determine if the database is mode ANSI with this query:
SELECT is_ansi FROM sysmaster:sysdatabases WHERE name = "<database name>";

In Oracle 11g, what permissions would I need to `SELECT * FROM V$TRANSPORTABLE_PLATFORM;`?

I am using AWS DMS to migrate an on-site Oracle 11g database to an Amazon RDS for Oracle DB instance of the same major version. I recently received this error:
2019-11-27T18:54:08 [SOURCE_CAPTURE ]E: Cannot execute SQL statement 'select tp.endian_format, tp.platform_name from v$database d, v$transportable_platform tp where d.platform_id = tp.platform_id'. OCI status '-1' [1020401] (oradcdc_redoutil.c:976)
2019-11-27T18:54:08 [TASK_MANAGER ]E: OCI error 'ORA-00942: table or view does not exist'; Cannot execute SQL statement 'select tp.endian_format, tp.platform_name from v$database d, v$transportable_platform tp where d.platform_id = tp.platform_id'. OCI status '-1'; Error executing source loop; Stream component failed at subtask 0, component st_0_XGQVEPQ6RSAXZT44XOZF7ERABI ; Stream component 's
My normal administrative schema can SELECT * FROM V$TRANSPORTABLE_PLATFORM; without issue, however, my new 'migration' schema cannot. Both have SELECT ANY TABLE privileges which, as described in Grant Select on All VIEWS [current and future] in Schema X, will allow the user to query any table or view in any schema in the database.
What permission am I missing in my migration schema? How does V$TRANSPORTABLE_PLATFORM differ from table/view objects in the database? What query could I run in order to obtain the type of V$TRANSPORTABLE_PLATFORM or any other database object?
A few things you may want to try:
Grant SELECT_CATALOG_ROLE to allow SELECT on system views
Add a manual GRANT to V_$TRANSPORTABLE_PLATFORM since V$TRANSPORTABLE_PLATFORM will reference that table
Ensure the schema is not ambiguous by adding SYS.

Laravel Execute sql queries from an sql file

Because for testing there's no testing database I use a manually generated sql script to clean a database clone of my production database. Assuming that my the legacy database is the following:
ohimesama
id: PK
namae: Varchar (200)
oujisama:
id: pk
namae: Varchar(200)
ohimesamagasuki:
id: pk
ohimesama_id: fk ohimesama
oujisama_id: fk oujisama
And the test database cleanup sql (cleanup.sql) script is:
DELETE * from ohimesama where namae not in ['Gardinelia', 'Jasmine'];
DELETE * from oujisama where namae not in ['Gaouron', 'Sasuke','Aladin'];
DELETE * from ohimesamagasuki where ohimesama_id not in (SELECT id from ohimesama) and oujisma not in
(SELECT id from oujisama);
And because I want to be able to execute all theese commands with one transaction IU want to be able to read the cleanup.sql file and execute the sql commands using Laravel Database Layer without the need for writing it manually.
How I can do that?
As seen in this medium article you can use this one single liner:
DB::unprepared(file_get_contents('cleanup.sql'));
The only issue is that sql commands are not chunked so in large sql files it may cause a slowdown. Also file_get_contents has a read limit as well.
In case of large sql files is reccomended to manually read and chunk it into selerate sql commands.
Also if a single command fails to get executed does not proceed to the next one as you would in via mysql or psql commands in a shell environment

How do I execute "use dbname" over Oracle dblink to Sybase?

How do I access tables in my user schema in Sybase from Oracle?
In isql I can do
use mydb
go
How do I select from mydb tables from Oracle using dblink NITSYB5?
This does not work:
select count(*) from "mydb"."lon_client_confirm_exec"#NITSYB5;
Error:
ORA-00942: table or view does not exist
[Oracle][ODBC Sybase Wire Protocol driver][SQL Server]"mydb"."lon_client_confirm_exec" not found. Specify owner.objectname or use sp_help to check whether the object exists (sp_help may produce lots of output).
{42S02,NativeErr = 208}
ORA-02063: preceding 3 lines from NITSYB5
00942. 00000 - "table or view does not exist"
*Cause:
*Action:
Error at Line: 3 Column: 30
NOTE: I don't work with Oracle and hence know nothing about Oracle's dblink, so fwiw ...
In Sybase ASE the fully qualified table name format is: <dbname>.<owner>.<table>
If you leave out the <owner> then the optimizer will first look for tables owned by the user running the query, then look for tables owned by dbo.
In your example it appears you've left out the <owner>. If the table is owned by your user or dbo then I'd suggest you try adding an additional period, eg:
select count(*) from mydb..lon_client_confirm_exec#NITSYB5;
NOTE: Add quotes as/if needed by Oracle's dblink.
SERVER 1 AND SERVER 2
open SSH server2 telnet server 1 host, its ok to done
su oracle
1) cd $ORACLE_HOME/bin
2) TNSPING database1 name
its ok done
create public database link
LINK_NAME
connect to
DB1USERNAME
identified by
111
using 'DB1NAME';
select * from dual#LINK_NAME, result x, finish.

How to copy data from one database/table to another database/table

I have written the following query using the documentation at: Oracle Documentation to copy some data from a database/table on my production server to database/table on Sandbox server.
COPY FROM username1/passwd1#<production_IP> to username2/passwd2#<sandbox_IP> INSERT TABLE_C (*) USING
(SELECT * FROM TABLE_C WHERE COL_A = 4884);
However, I am constantly running into Connection failed error. Is there anything wrong with the query?
In a typical Oracle environment, you have TNS names set up. That's a service to lookup the connection parameters for Oracle instances given an SID or service name. In it's simplest form, TNS names is a file called tnsnames.ora located by the environment variable TNS_ADMIN (which points to the directory where the file is).
Given the SIDs PROD and SANDBOX, you can then copy the tables from the SQLPLUS command line utility:
COPY FROM username1/passwd1#PROD to username2/passwd2#SANDBOX
INSERT TABLE_C (*) USING (SELECT * FROM TABLE_C WHERE COL_A = 4884);
Please note that this COPY command only supports a limited set of Oracle datatypes: char, date, long, varchar2, number.
If you don't have TNS names set up, you'll need to know the host name or IP address, the port number and the service name. The syntax then becomes:
COPY FROM username1/passwd1#//192.168.3.17:1521/PROD_SERVICE to username2/passwd2#//192.168.4.17:1521/SANDBOX_SERVICE
INSERT TABLE_C (*) USING (SELECT * FROM TABLE_C WHERE COL_A = 4884);
To determine the SID and/or service name, you best have a look into the TNSNAMES.ORA file on the database server itself. If you are able to login to the database, you can use the following queries to determine the SID and service name (but don't ask me which is which):
select name from v$database;
select * from global_name;
select instance_number, instance_name, host_name from v$instance;
Copy gpl_project/gpl_project#gpldatar to gpl_project/gpl_project#gplrdp. Replace BGROUPMASTER using select * from BGROUPMASTER.
The following is the solution that I used. I created a link the remote database then used an INSERT command to populate the data.
CREATE DATABASE LINK database_link_name
CONNECT TO my_user_name IDENTIFIED BY my_password
USING 'tns_name';
INSERT INTO my_table SELECT * FROM my_remote_table#database_link_name;
If you want to get rid of the database link after the work. Use the following:
DROP DATABASE LINK database_link_name;
See this link for helpful information:
https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:9532217300346683472

Resources