replace partition for a table in KDB - kdb

I have a KDB table which is splayed and partitioned:
db/2018.10.01/mydata/...columns
db/2018.10.02/mydata/...columns
db/2018.10.03/mydata/...columns
I want to replace partition db/2018.10.02/mydata/ with the one containing updated values, but dont know how to do it.
I have tried this:
`:D:/db/2018.10.02/mydata/ set delete date from mydata
Getting this error:
(Roundtrip: 000ms)
ERROR: 'par
(trying to update a physically partitioned table)
Any help is appreciated.

The par error is coming from the delete query. delete date from mydata as you must be trying to operate on the partitioned table itself. You should load in the data you need from 2018.10.02, update and save down.
Splayed tables with sym columns also need to be enumerated with .Q.en and any attributes may need reapplied after the update such as the parted attribute on a sym column.
Something like this:
// load and update data
res:delete date from select from mydata where date = 2018.10.02;
res:update {your updates} from res;
// apply attribute if needed
res:#[res;first exec c from meta[mydata] where a = `p;`p#];
// save down
// assuming the hdb root / sym file is in `:D:/db
`:D:/db/2018.10.02/mydata/ set .Q.en[`:D:/db;res];
https://code.kx.com/q/ref/dotq/#qen-enumerate-varchar-cols
https://code.kx.com/q/ref/set-attribute/
https://code.kx.com/q/kb/splayed-tables/#enumerating-symbol-columns

Related

UPSERT from table with different table sizes

I'm getting the error:
ERROR: column "some_col_name" does not exist Hint: There is a column named "some_col_name" in table "usert_test", but it cannot be referenced from this part of the query.
On UPSERT The cause of this error is that the source table (read in from API) doesn't always have the same number of fields as the table I'm looking to UPSERT. Within the UPSERT process is there a way to handle this? So far I've tried the below:
INSERT INTO scratch."usert_test" (many_cols)
SELECT *
FROM scratch.daily_scraper
ON CONFLICT (same_unique_id)
DO UPDATE
SET
many_fields = excluded.many_fields;
Name each column specifically in every instance.
insert into scratch."usert_test" (column_name1, column_name2, column_name3,column_name3)
select cola, colb, colc, colf
from scratch.daily_scraper
on conflict (column_name1, column_name4)
do update
set
column_name3 = excluded.column_name3
, column_name2 = excluded.column_name2;
How ever many columns you have properly name every one. (IMHO) As you should always do.

Postgres: update value of TEXT column (CLOB)

I have a column of type TEXT which is supposed to represent a CLOB value and I'm trying to update its value like this:
UPDATE my_table SET my_column = TEXT 'Text value';
Normally this column is written and read by Hibernate and I noticed that values written with Hibernate are stored as integers (perhaps some internal Postgres reference to the CLOB data).
But when I try to update the column with the above SQL, the value is stored as a string and when Hibernate tries to read it, I get the following error: Bad value for type long : ["Text value"]
I tried all the options described in this answer but the result is always the same. How do I insert/update a TEXT column using SQL?
In order to update a cblob created by Hibernate you should use functions to handling large objects:
the documentation can be found in the following links:
https://www.postgresql.org/docs/current/lo-interfaces.html
https://www.postgresql.org/docs/current/lo-funcs.html
Examples:
To query:
select mytable.*, convert_from(loread(lo_open(mycblobfield::int, x'40000'::int), x'40000'::int), 'UTF8') from mytable where mytable.id = 4;
Obs:
x'40000' is corresponding to read mode (INV_WRITE)
To Update:
select lowrite(lo_open(16425, x'60000'::int), convert_to('this an updated text','UTF8'));
Obs:
x'60000' = INV_WRITE + INV_READ is corresponding to read and write mode (INV_WRITE + IV_READ).
The number 16425 is an example loid (large object id) which already exists in a record in your table. It's that integer number you can see as value in the blob field created by Hinernate.
To Insert:
select lowrite(lo_open(lo_creat(-1), x'60000'::int), convert_to('this is a new text','UTF8'));
Obs:
lo_creat(-1) generate a new large object a returns its loid

How to add a column to a table using combined columns from the same table?

I needed basic help on how to combine columns into one new column in the same table. I have done the below as a SELECT command and it works fine. I just don't know how to add it to the table permanently so that it becomes part of the table.
SELECT *, concat(z41, z42, z43, z44) AS option_3,
concat(z411, z412, z413, z421, z422, z423, z431, z432, z433, z434, z444,z443, z442, z441) AS option_4,
concat(z4211, z4212, z4213, z4214, z4215, z4311, z4312, z4313, z4314, z4431, z4432, z4433, z4434, z4421, z4422, z4423, z4424, z4425, z4426) AS option_5
FROM combined_full
Like others have mentioned, you are probably better off using a view. But if you really need this computed data in column then you can do this:
ALTER TABLE combined_full ADD COLUMN option_3 varchar,
ADD COLUMN option_4 varchar,
ADD COLUMN option_5 varchar;
UPDATE combined_full
SET option_3 = concat(z41, z42, z43, z44),
option_4 = concat(z411, z412, z413, z421, z422, z423, z431, z432, z433, z434, z444,z443, z442, z441),
option_5 = concat(z4211, z4212, z4213, z4214, z4215, z4311, z4312, z4313, z4314, z4431, z4432, z4433, z4434, z4421, z4422, z4423, z4424, z4425, z4426);
When adding new rows to the table, you should either also enter values for these three new columns, or create an insert trigger so that the values are automatically calculated as you do above.
"so that it becomes part of the table" - you can't. Unfortunately Postgres (as of 9.6) has no (persisted) computed columns.
If the expression is not very expensive to calculate and you don't need an index on it, I would suggest to create a view that contains the expression.
Given the example in your question, this should be good enough in your case as concatenating values isn't really that expensive.
If you really think you need to persist the calculation of the expression because e.g. you want to create an index on that or you constantly use that expression in a where clause, you will need to add a regular column to the table and a trigger that updates the expression when a row is inserted or updated.

How to update an XML column in DB2 with XMLQuery?

I want to update an XML column in DB2 with dynamic values or you can say with values that I'll pick from another table and insert them in the xml column.
I know how to insert a node along with its value that we provide by
hard coding it, e.g.
<data>some_value</data>
I want to do it in the following way:
UPDATE my_table SET my_table_column = XMLQuery(..... <data>???</data>)
WHERE my_table_id = other_table_id;
Where I place ??? I need a kind of select statement here which will come up with actual value for the node.

Postgresql, query results to new table

Windows/NET/ODBC
I would like to get query results to new table on some handy way which I can see through data adapter but I can't find a way to do it.
There is no much examples around to satisfy beginner's level on this.
Don't know temporary or not but after seeing results that table is no more needed so I can delete it 'by hand' or it can be deleted automatically.
This is what I try:
mCmd = New OdbcCommand("CREATE TEMP TABLE temp1 ON COMMIT DROP AS " & _
"SELECT dtbl_id, name, mystr, myint, myouble FROM " & myTable & " " & _
"WHERE myFlag='1' ORDER BY dtbl_id", mCon)
n = mCmd.ExecuteNonQuery
This run's without error and in 'n' I get correct number of matched rows!!
But with pgAdmin I don't see those table no where?? No matter if I look under opened transaction or after transaction is closed.
Second, should I define columns for temp1 table first or they can be made automatically based on query results (that would be nice!).
Please minimal example to illustrate me what to do based on upper code to get new table filled with query results.
A shorter way to do the same thing your current code does is with CREATE TEMPORARY TABLE AS SELECT ... . See the entry for CREATE TABLE AS in the manual.
Temporary tables are not visible outside the session ("connection") that created them, they're intended as a temporary location for data that the session will use in later queries. If you want a created table to be accessible from other sessions, don't use a TEMPORARY table.
Maybe you want UNLOGGED (9.2 or newer) for data that's generated and doesn't need to be durable, but must be visible to other sessions?
See related: Is there a way to access temporary tables of other sessions in PostgreSQL?