Vertica include column names in output, but not row count footer - vertica

I am running some Vertica SQL queries from the command line and saving them to CSVs.
I want to keep column names, so I do not use the -t option. The problem is that I now am also left with the footer which gives the row count (e.g. (20 rows). I know that I could remove this footer in a separate command (as it will always be in the last row), but I was wondering if there is a more elegant solution.
I have been looking at the documentation here:
https://my.vertica.com/docs/7.1.x/HTML/Content/Authoring/ConnectingToHPVertica/vsql/CommandLineOptions.htm

Use \pset footer off.
More info on the metacommand is available at the documentation.
Example:
dbadmin=> select count(*) from sessions;
count
-------
5
(1 row)
dbadmin=> \pset footer off
Default footer is off.
dbadmin=> select count(*) from sessions;
count
-------
5

Related

How to insert multiple values from checkbox group in oracle Apex?

I have an order table(id_order,id_category) and category table(id_category,description).
How can I insert to an order, more than 1 type of category in oracle Apex app?
One option is to use a shuttle item; it'll let you easily move desired categories from its left to right side. The result is a semi-colon separated list of values. For example, if you chose categories 1, 5 and 7, result is 1;5;7 so - in order to insert them properly into the order table, you'll first have to split them to rows.
How? Use apex_string.split:
SQL> select * from table(apex_string.split('1;5;7', ';'));
COLUMN_VALUE
--------------------------------------------------------------------------------
1
5
7
SQL>
All rows would share the same order_id, I presume (a sequence might be a good choice for its value).

SQLPLUS Records not correctly showing

I am currently trying to create a report using SQLPLUS, but the output keeps splitting after showing record #11.
I would like to see all the records under one output. The second columns 'Schema' and 'TOTAL_SIZE_IN_GB' are unnecessary and I want to get rid of them. How can I fix this?
Code:
set verify off
set feedback off
column owner format a15 heading 'Schema'
column total_size format 990.99 heading 'TOTAL_SIZE_IN_GB'
SELECT owner, ROUND(SUM(bytes)/1024/1024/1024, 2) total_size
FROM dba_segments
where (segment_type='TABLE' and owner like '%OBS%')
or (segment_type='TABLE' and owner like '%USR%')
group by owner
order by total_size DESC;
How many rows are shown "per page" is controlled by a setting, pagesize. (This is all SQL*Plus stuff, it has nothing to do with the query itself.) Issue the following SQL*Plus command before you run your query:
set pagesize 3000
(or some other number larger than the number of rows in your output).
Obviously, if you have 10000 rows in the output they will still be broken into "pages" of 3000 rows each, but I hope you are not actually creating a report, for human reading, with 10000 rows. No one will read that.
You could also set the pagesize to zero, but then you won't print column headers anymore; likely not what you need.

Get all columns from a table in Monetdb

I have to study a table on monetdb that probably has many columns.
When I do
SELECT * from cat.data limit 1;
I get
1 tuple !5600 columns dropped!
Which I interpret as not getting all the columns from the console.
I am using mclient to connect to the database.
I tried withe DESC, DESCRIBE - didnt work. Any help?
Indeed. See mclient --help
It is possible to extend the width of your output to see more columns.
Alternatively, within the mclient console use the \d tablename command
You need to use \w-1 command before executing your query.
sql>\w-1
sql>SELECT * from cat.data limit 1 ;
This will show all the columns in the terminal. The text will be wrapped.

Oracle truncating column

I have the following query.
insert into ORDER_INFO(ORDINF_PK,ORDINF_LGNDET_PK_FK,MEDIA_TYPE,ORDINF_MUSIC_FK,DAT)
values (1,1,'Music',21,TO_DATE('14-OCT-2015','DD-MON-YYYY'));
insert into ORDER_INFO(ORDINF_PK,ORDINF_LGNDET_PK_FK,MEDIA_TYPE,ORDINF_MUSIC_FK,ORDINF_SERIES_FK,DAT)
values (2,2,'Series',71,23,TO_DATE('07-NOV-2015','DD-MON-YYYY'));
however when I do:
select * from ORDER_INFO;
I get:
truncating (as requested) before column ORDINF_SERIES_FK
truncating (as requested) before column ORDINF_MOVIES_FK
ORDINF_PK ORDINF_LGNDET_PK_FK MEDIA_TYPE ORDINF_MUSIC_FK DAT
---------- ------------------- -------------------- --------------- ---------
1 1 Music 21 14-NOV-14
2 2 Series 71 07-NOV-15
I understand that it is truncating ORDINF_MOVIES_FK because there is no entry in that column, but why is it truncating the column ORDINF_SERIES_FK?
I managed to solve the issue, I did this.
set wrap on;
set pagesize 50000;
set linesize 120;
link here: http://www.anattatechnologies.com/q/2012/01/sqlplus-pagesize-and-linesize/
Pay attention - both rows inserted and ARE in the database, so INSERT succeeded.
The warning you get is a warning from SQLPlus program that means that column is display not with full width (maybe the definition of column is long and SQLPlus decides to show column shorter because data you have in there is short).
You do not need to worry about this in any case.
See this link for more explanation about SQL*Plus wrap.

select only new row in oracle

I have table with "varchar2" as primary key.
It has about 1 000 000 Transactions per day.
My app wakes up every 5 minute to generate text file by querying only new record.
It will remember last point and process only new records.
Do you have idea how to query with good performance?
I am able to add new column if necessary.
What do you think this process should do by?
plsql?
java?
Everyone here is really really close. However:
Scott Bailey's wrong about using a bitmap index if the table's under any sort of continuous DML load. That's exactly the wrong time to use a bitmap index.
Everyone else's answer about the PROCESSED CHAR(1) check in ('Y','N')column is right, but missing how to index it; you should use a function-based index like this:
CREATE INDEX MY_UNPROCESSED_ROWS_IDX ON MY_TABLE
(CASE WHEN PROCESSED_FLAG = 'N' THEN 'N' ELSE NULL END);
You'd then query it using the same expression:
SELECT * FROM MY_TABLE
WHERE (CASE WHEN PROCESSED_FLAG = 'N' THEN 'N' ELSE NULL END) = 'N';
The reason to use the function-based index is that Oracle doesn't write index entries for entirely NULL values being indexed, so the function-based index above will only contain the rows with PROCESSED_FLAG = 'N'. As you update your rows to PROCESSED_FLAG = 'Y', they'll "fall out" of the index.
Well, if you can add a new column, you could create a Processed column, which will indicate processed records, and create an index on this column for performance.
Then the query should only be for those rows that have been newly added, and not processed.
This should be easily done using sql queries.
Ah, I really hate to add another answer when the others have come so close to nailing it. But
As Ponies points out, Oracle does have a hidden column (ORA_ROWSCN - System Change Number) that can pinpoint when each row was modified. Unfortunately, the default is that it gets the information from the block instead of storing it with each row and changing that behavior will require you to rebuild a really large table. So while this answer is good for quieting the SQL Server fella, I'd not recommend it.
Astander is right there but needs a few caveats. Add a new column needs_processed CHAR(1) DEFAULT 'Y' and add a BITMAP index. For low cardinality columns ('Y'/'N') the bitmap index will be faster. Once you have the rest is pretty easy. But you've got to be careful not select the new rows, process them and mark them as processed in one step. Otherwise, rows could be inserted while you are processing that will get marked processed even though they have not been.
The easiest way would be to use pl/sql to open a cursor that selects unprocessed rows, processes them and then updates the row as processed. If you have an aversion to walking cursors, you could collect the pk's or rowids into a nested table, process them and then update using the nested table.
In MS SQL Server world where I work, we have a 'version' column of type 'timestamp' on our tables.
So, to answer #1, I would add a new column.
To answer #2, I would do it in plsql for performance.
Mark
"astander" pretty much did the work for you. You need to ALTER your table to add one more column (lets say PROCESSED)..
You can also consider creating an INDEX on the PROCESSED ( a bitmap index may be of some advantage, as the possible value can be only 'y' and 'n', but test it out ) so that when you query it will use INDEX.
Also if sure, you query only for every 5 mins, check whether you can add another column with TIMESTAMP type and partition the table with it. ( not sure, check out again ).
I would also think about writing job or some thing and write using UTL_FILE and show it front end if it can be.
If performance is really a problem and you want to create your file asynchronously, you might want to use Oracle Streams, which will actually get modification data from your redo log withou affecting performance of the main database. You may not even need a separate job, as you can configure Oracle Streams to do Asynchronous replication of the changes, through which you can trigger the file creation.
Why not create an extra table that holds two columns. The ID column and a processed flag column. Have an insert trigger on the original table place it's ID in this new table. Your logging process can than select records from this new table and mark them as processed. Finally delete the processed records from this table.
I'm pretty much in agreement with Adam's answer. But I'd want to do some serious testing compared to an alternative.
The issue I see is that you need to not only select the rows, but also do an update of those rows. While that should be pretty fast, I'd like to avoid the update. And avoid having any large transactions hanging around (see below).
The alternative would be to add CREATE_DATE date default sysdate. Index that. And then select records where create_date >= (start date/time of your previous select).
But I don't have enough data on the relative costs of setting a sysdate as default vs. setting a value of Y, updating the function based vs. date index, and doing a range select on the date vs. a specific select on a single value for the Y. You'll probably want to preserve stats or hint the query to use the index on the Y/N column, and definitely want to use a hint on a date column -- the stats on the date column will almost certainly be old.
If data are also being added to the table continuously, including during the period when your query is running, you need to watch out for transaction control. After all, you don't want to read 100,000 records that have the flag = Y, then do your update on 120,000, including the 20,000 that arrived when you query was running.
In the flag case, there are two easy ways: SET TRANSACTION before your select and commit after your update, or start by doing an update from Y to Q, then do your select for those that are Q, and then update to N. Oracle's read consistency is wonderful but needs to be handled with care.
For the date column version, if you don't mind a risk of processing a few rows more than once, just update your table that has the last processed date/time immediately before you do your select.
If there's not much information in the table, consider making it Index Organized.
What about using Materialized view logs? You have a lot of options to play with:
SQL> create table test (id_test number primary key, dummy varchar2(1000));
Table created
SQL> create materialized view log on test;
Materialized view log created
SQL> insert into test values (1, 'hello');
1 row inserted
SQL> insert into test values (2, 'bye');
1 row inserted
SQL> select * from mlog$_test;
ID_TEST SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
---------- ----------- --------- --------- ---------------------
1 01/01/4000 I N FE
2 01/01/4000 I N FE
SQL> delete from mlog$_test where id_test in (1,2);
2 rows deleted
SQL> insert into test values (3, 'hello');
1 row inserted
SQL> insert into test values (4, 'bye');
1 row inserted
SQL> select * from mlog$_test;
ID_TEST SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$
---------- ----------- --------- --------- ---------------
3 01/01/4000 I N FE
4 01/01/4000 I N FE
I think this solution should work..
What you need to do following steps
For the first run, you will have to copy all records. In first run you need to execute following query
insert into new_table(max_rowid) as (Select max(rowid) from yourtable);
Now next time when you want to get only newly inserted values, you can do it by executing follwing command
Select * from yourtable where rowid > (select max_rowid from new_table);
Once you are done with processing above query, simply truncate new_table and insert max(rowid) from yourtable
I think this should work and would be fastest solution;

Resources