How to convert oid datatype to varchar during updation - postgresql

i want update a column image_name data type is oid
using image1 column datatype is varchar
during the updation I'm getting error like
update mst_memberdetail set image_name=image1;
column "image" is of type oid but expression is of type character varying
can u please tell me how to convert explicitly datatype

I assume that image1 is an OID that refers to an LOB? If so, you probably don't want to update that directly to varchar since you will get escaped binary (possibly hexadecimal). This is something you want to do in a client library, not in the db backend, if that is your use case.
Alternatively you could write a PL/Perl function to unescape the binary, and use the lo_* functions to read it, pass it to PL/Perl and update the varchar, but if you have encoding issues that will fail, and it will be slow.
If you are using lobs I would just recommend leaving them as is.

Related

Creating a postgres column which allows all datatypes

I want to create a logging table which tracks changes in a certain table, like so:
CREATE TABLE logging.zaak_history (
event_id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
tstamp timestamp DEFAULT NOW(),
schemaname text,
tabname text,
columnname text,
operation text,
who text DEFAULT current_user,
new_val <any_type>,
old_val <any_type>
);
However, the column that I want to track can take different datatypes, such as text, boolean and numeric. Is there a datatype that support the functionality?
Currently I am thinking about storing is as jsonb, as this will deal with the datatype in the json formatting, but I was wondering if there is a better way.
There is no postgres data type that isn't strongly typed, because the "any" data type that is available as a pseudo type cannot be used as a column (it can be used in functions, etc.)
You could store the binary representation of your data, because every type does have a binary representation.
Your approach of using JSON seems more flexible, as you can also store meta data (such as type information).
However, I recommend looking at how other people have solved the same issue for alternative ideas. For example, most wikis store a copy of the entire record for history, which is easy to reconstruct, can be referenced independently, and has no typing issues.

Convert a BLOB to VARCHAR instead of VARCHAR FOR BIT

I have a BLOB field in a table that I am selecting. This field data consists only of JSON data.
If I do the following:
Select CAST(JSONBLOB as VARCHAR(2000)) from MyTable
--> this returns the value in VARCHAR FOR BIT DATA format.
I just want it as a standard string or varcher - not in bit format.
That is because I need to use JSON2BSON function to convert the JSON to BSON. JSON2BSON accepts a string but it will not accept a VarChar for BIT DATA type...
This conversation should be easy.
I am able to do the select as a VARCHAR FOR BIT DATA.. Manually COPY it using the UI. Paste it into a select literal and convert that to BSON. I need to migrate a bunch of data in this BLOB from JSON to BSON, and doing it manually won't be fast. I just want to explain how simple of a use case this should be.
What is the select command to essentially get this to work:
Select JSON2BSON(CAST(JSONBLOB as VARCHAR(2000))) from MyTable
--> Currently this fails because the CAST converts this (even though its only text characters) to VARCHAR for BIT DATA type and not standard VARCHAR.
What is the suggestion to fix this?
DB2 11 on Windows.
If the data is JSON, then the table column should be CLOB in the first place...
Having the table column a BLOB might make sense if the data is actually already BSON.
You could change the blob into a clob using the converttoclob procedure then you should be ok.
https://www.ibm.com/support/knowledgecenter/SSEPGG_11.5.0/com.ibm.db2.luw.apdv.sqlpl.doc/doc/r0055119.html
You can use this function to remove the "FOR BIT DATA" flag on a column
CREATE OR REPLACE FUNCTION DB_BINARY_TO_CHARACTER(A VARCHAR(32672 OCTETS) FOR BIT DATA)
RETURNS VARCHAR(32672 OCTETS)
NO EXTERNAL ACTION
DETERMINISTIC
BEGIN ATOMIC
RETURN A;
END
or if you are on Db2 11.5 the function SYSIBMADM.UTL_RAW.CAST_TO_VARCHAR2 will also work

MariaDB CAST OR CONVERT Function is not work

my table has a varchar(64) column ,when i try to convert it to char(36), it not work.
SELECT
CONVERT('00edff66-3ef4-4447-8319-fc8eb45776ab',CHAR(36)) AS A,
CAST('00edff66-3ef4-4447-8319-fc8eb45776ab' AS CHAR(36)) as B
this is desc result
It's like this because it is derived from MySQL where there was no CAST AS VARCHAR option. In MySQL there was only CAST AS CHAR which was producing VARCHAR. Here are what the supported options were in MySQL 5.6:
https://dev.mysql.com/doc/refman/5.6/en/cast-functions.html#function_cast
See they explicitly mention that "No padding occurs for values shorter than N characters". Later MariaDB started adding CAST AS VARCHAR only to make it more cross-platform compatible with systems like Oracle, Postgre, MSSQL, etc.:
https://jira.mariadb.org/browse/MDEV-11283
But still CAST AS CHAR and CAST AS VARCHAR is the same. And I guess it should be the same. Why do you need the fixed length datatype in RAM? It should matter only when you store it.
For example if you have a table with CHAR datatype:
CREATE TABLE tbltest(col CHAR(10));
and you insert casted as VARCHAR data for example:
INSERT INTO tbltest(col) VALUES(CAST('test' AS VARCHAR(5)));
it will be stored as CHAR(10) datatype. Because that's what the table uses.

Why can't Update set change data type Postgres

I have a CSV which contains numbers stored as strings example: 1,200 when loading in these are stored as VARCHAR
I'd like to store these as integers. So tested the below;
update data
set stringy_number = replace (stringy_number,',','')::integer
This runs and removes the , from the number but doesn't change the character type. I then tried;
update data
set stringy_number::integer = replace (stringy_number,',','')::integer
Which threw a syntax error. At which point I switched to the below which worked, but I don't understand why I can't set a data type along with an update
alter table data
alter column stringy_number type integer using replace(stringy_number,',','')::integer;
update works on the values. You can cast from a datatype to another, but the result is still cast to to underlying column type.
--> you can save a "number" in a text column because it is easy to cast a number to a text. You cannot save a letter in a numerical column because the cast cannot (easily) be done.
alter column works on the entire column type. When changing the type, you can supply a custom transformation method allowing the old data to match the new data type.

Npgsql.PostgresException: Column cannot be cast automatically to type bytea

Using EF-Core for PostgresSQL, I have an entity with a field of type byte but decided to change it to type byte[]. But when I do migrations, on applying the migration file generated, it threw the following exception:
Npgsql.PostgresException (0x80004005): 42804: column "Logo" cannot be
cast automatically to type bytea
I have searched the internet for a solution but all I saw were similar problems with other datatypes and not byte array. Please help.
The error says exactly what is happening... In some cases PostgreSQL allows for column type changes (e.g. int -> bigint), but in many cases where such a change is non-trivial or potentially destructive, it refuses to do so automatically. In this specific case, this happens because Npgsql maps your CLR byte field as PostgreSQL smallint (a 2-byte field), since PostgreSQL lacks a 1-byte data field. So PostgreSQL refuses to cast from smallint to bytea, which makes sense.
However, you can still do a migration by writing the data conversion yourself, from smallint to bytea. To do so, edit the generated migration, find the ALTER COLUMN ... ALTER TYPE statement and add a USING clause. As the PostgreSQL docs say, this allows you to provide the new value for the column based on the existing column (or even other columns). Specifically for converting an int (or smallint) to a bytea, use the following:
ALTER TABLE tab ALTER COLUMN col TYPE BYTEA USING set_bytea(E'0', 0, col);
If your existing column happens to contain more than a single byte (should not be an issue for you), it should get truncated. Obviously test the data coming out of this carefully.