Connect by level in Postgres on a sequence - oracle

I need to convert a query from Oracle to Postgres which uses connect by level on a sequence in Oracle.
I know that connect by level is not available in Postgres. I couldn't find an alternate for this using recursive cte.
In Oracle if I run this query.
create sequence ID_SEQ;
select ID_SEQ.nextval from DUAL connect by level <= 3;
I will get the following result
1
2
3
I need the same in Postgres. Please share some solutions if anyone has any idea.
Thanks in advance
Gokul.

The direct translation of that query is to use generate_series() and nextval()
select nextval('id_seq')
from generate_series(1,3);
This will advance the sequence three times.
If however the goal is to set a specific value for an existing sequence (which requires such a hack in Oracle), just use setval():
select setval('id_seq', 3);

Related

How to filter by column length in ODI?

I have a mapping in Oracle data integrator that works correctly, I need to filter by a column and exclude the rows where the length of that column equals 3. I can't find the correct function to do it. I already tried with LENGTH (column) = 3 and it doesn't work...
Does anyone know the way?
Oracle Data Integrator is most of the time generating code that is pushed down to the underlying technology. So it depends which technology you are using.
For instance if you are using an IKM using the Oracle technology, the code will be execute by the Oracle database. In that case LENGTH(column_name) <> 3 should work.

Nifi executeSql with 30 threads very slow

We are using HDF to fetch large data from oracle. We have a generateTableFetch to create partition of 8000 records which create query like below :
Select * from ( Select a.*, ROWNUM rnum FROM (SELECT * FROM OPUSER.DEPENDENCY_TYPES WHERE (1=1))a WHERE ROWNUM <= 368000) WHERE rnum > 361000
Now this query is taking almost 20-25min to return from oracle.
Is there anything wrong that we are doing wrong or any configuration changes we can do.
Nifi uses jdbc connection so is there any oracle side configuration for that.
Also if we somehow add parallelism hint to the query example /parallel(c,2)/. WIll this help?
I'm guessing you're using Oracle 11 (or less) and have selected Oracle as the database type. Since LIMIT/OFFSET wasn't introduced until Oracle 12, NiFi uses the nested SELECT with ROWNUM approach to ensure each "page" of data contains unique values. If you are using Oracle 12+, make sure to use the Oracle 12+ database adapter instead, as it can leverage the LIMIT/OFFSET capabilities resulting in a faster query. Also make sure you have the appropriate index(es) in place to help with query execution.
As of NiFi 1.7.0, you might also consider setting the Column for Value Partitioning property. If you have a column (perhaps your DEPENDENCY_TYPES column) that is fairly uniformly distributed, and is not "too sparse" in relation to your Partition Size property value, GenerateTableFetch can use the column's values rather than the ROWNUM approach, resulting in faster queries. See NIFI-5143 and the GenerateTableFetch documentation for more details.
If you need to add hints to the JDBC session, then as of NiFi 1.9.0 (see NIFI-5780 for more details) you can add pre- and post-query statements to ExecuteSQL.

How query from another database that is in another machine/server

I've been looking for answer to this but I can't seem to find the right answer online and my problem goes like this.
I'm trying to query a set of records from another table which is in an another database installed in a different machine. To make it clearer:
My stored procedure is running on IP: 192.168.XX.X1. I get to retrieve all the information I need in this server but I have another set of information or records that can only be retrieved from IP: 192.168.XX.X2.
I was thinking to achieve something like:
DECLARE
-- given that both queries will only return 1 record
CURSOR IS curSample1
SELECT * FROM Database1.Table1;
colSample curSample1%ROWTYPE;
CURSOR IS curSample2
SELECT * FROM Database2.Table1;
colSample curSample2%ROWTYPE;
vText1 VARCHAR(20);
vText2 VARCHAR(20);
BEGIN
OPEN curSample1;
LOOP
FETCH curSample1 INTO colSample1;
EXIT WHEN curSample1%NOTFOUND;
vText1 := colSample1.Column1;
END LOOP;
CLOSE curSample1;
OPEN curSample2;
LOOP
FETCH curSample2 INTO colSample2;
EXIT WHEN curSample2%NOTFOUND;
vText2 := colSample2.Column2;
END LOOP;
CLOSE curSample2;
dbms_output.put_line(vText1 || ',' || vText2);
END;
Any help you could provide will be much appreciated. Thank you very much.
Note: I'm trying this approach as this is the only way we could possibly do it as of now. Thanks again.
You will have to create a db link between your database 1 and database 2. For creating a database link it is not required to have both databases on the same server. Since in your case the databases are on different server you can start with the following steps.
You need a tns entry (pointing to database 2) in the tnsnames.ora file on your database 1 server. You can check if you have this entry by connecting to SQLPLUS from your database 1 machine to database 2.
sqlplus <username>/<password>#<tnsnames of database2>
If you are able to connect from your database 1 server then you can proceed with the following steps for creating the db link.
CREATE DATABASE LINK <dblink_name> CONNECT TO <username> IDENTIFIED BY <password> USING <tnsnames of database2>
Post this you can test your database link by running the following SQL command.
select * from Table#<dblink_name>;
as i know you cannot query data cross database directly.
1,maybe you can use DBlink or DataSync to let the data which in other database can be query.
2,instead of pl/sql procedure, use other development language to do cross DB process is a good idea(ex independent java program).
3,instead of pl/sql procedure, use Oracle Java Procedure to do this.

Oracle accessing multiple databases

I'm using Oracle SQL Developer version 4.02.15.21.
I need to write a query that accesses multiple databases. All that I'm trying to do is get a list of all the IDs present in "TableX" (There is an instance of Table1 in each of these databases, but with different values) in each database and union all of the results together into one big list.
My problem comes with accessing more than 4 databases -- I get this error: ORA-02020: too many database links in use. I cannot change the INIT.ORA file's open_links maximum limit.
So I've tried dynamically opening/closing these links:
SELECT Local.PUID FROM TableX Local
UNION ALL
----
SELECT Xdb1.PUID FROM TableX#db1 Xdb1;
ALTER SESSION CLOSE DATABASE LINK db1
UNION ALL
----
SELECT Xdb2.PUID FROM TableX#db2 Xdb2;
ALTER SESSION CLOSE DATABASE LINK db2
UNION ALL
----
SELECT Xdb3.PUID FROM TableX#db3 Xdb3;
ALTER SESSION CLOSE DATABASE LINK db3
UNION ALL
----
SELECT Xdb4.PUID FROM TableX#db4 Xdb4;
ALTER SESSION CLOSE DATABASE LINK db4
UNION ALL
----
SELECT Xdb5.PUID FROM TableX#db5 Xdb5;
ALTER SESSION CLOSE DATABASE LINK db5
However this produces 'ORA-02081: database link is not open.' On whichever db is being closed out last.
Can someone please suggest an alternative or adjustment to the above?
Please provide a small sample of your suggestion with syntactically correct SQL if possible.
If you can't change the open_links setting, you cannot have a single query that selects from all the databases you want to query.
If your requirement is to query a large number of databases via database links, it seems highly reasonable to change the open_links setting. If you have one set of people telling you that you need to do X (query data from a large number of tables) and another set of people telling you that you cannot do X, it almost always makes sense to have those two sets of people talk and figure out which imperative wins.
If we can solve the problem without writing a single query, then you have options. You can write a bit of PL/SQL, for example, that selects the data from each table in turn and does something with it. Depending on the number of database links involved, it may make sense to write a loop that generates a dynamic SQL statement for each database link, executes the SQL, and then closes the database link.
If you want need to provide a user with the ability to run a single query that returns all the data, you can write a pipelined table function that implements this sort of loop with dynamic SQL and then let the user query the pipelined table function. This isn't really a single query that fetches the data from all the tables. But it is as close as you're likely to get without modifying the open_links limit.

need to connect to two different db from sqlplus

I need to take information from two different data bases.
select * from TABLE_ONDB2 where column_on_db2 in ( select column_on_db1 from TABLE_ONDB1 );
Problem is both are on different db instances so I am not able to figure out how to put table names and column names etc.
I hope my question is clear.
I'd try to do it with a Database Link:
http://download.oracle.com/docs/cd/B28359_01/server.111/b28310/ds_concepts002.htm
That is, however, not a SQL*Plus feature. It works by makeing a connection from DB2 to DB1 (the database is doing that).
You can then query both tables from DB2 with the '#db-link' name notation. e.g.,
select *
from TABLE_ONDB2
where column_on_db2
in (select column_on_db1 from TABLE_ONDB1#DB_LINK_NAME);
^^^^^^^^^^^^^
The benefit is that you can access the table in all different ways, also as a join.

Resources