How to set an object to null - postgresql

How to set an object to null.
Ex:
my object samp contains three fileds
samp.field1,samp.field2.sampfield3
If i set samp:= null;
im getting errors is there a way to set the object value to null.

An sql database does not know about objects, it deals with rows in table.
To remove a row use DELETE :
e.g. :
DELETE FROM samp WHERE id = 12345;
DELETE FROM samp WHERE field1 = 'Delete Me';
The first example is typical to remove individual rows uing their primary key (id in this case)
The second example will remove a group of rows which have a speciic value for a field.

Related

Renaming all existing attributes in an array of Json objects

I work with Postgres db.
For example - there is a table
CREATE TABLE public.json_objects(id serial primary key, objects text);
it stores such an arrays of json
INSERT INTO public.json_objects (objects) VALUES ('[{"name":"Ivan"}]'), ('[{"name":"Petr"}, "surname":"Petrov"}]'), ('[{"form":"OOO"}, {"city":"Kizema"}]');
How can I replace the attribute "name" with "first name" or "surname" with "second name" everywhere?
I am using update with the select - subquery.
In this case, a replacement will occur, but if the attribute does not exist in the json object, then it will be added to the json with a null value (and this should not be)
WITH updated_table AS (SELECT id, jsonb_agg(new_field_json) as new_fields_json
FROM (SELECT id, jsonb_array_elements(json_objects.objects::jsonb) - 'name' || jsonb_build_object('first name', jsonb_array_elements(json_objects.objects::jsonb) -> 'name') new_field_json FROM public.json_objects) r group by id) UPDATE public.json_objects SET objects = updated_table.new_fields_json FROM updated_table where json_objects.id = updated_table.id
This seems to be a single operation, so you can just use the regexp_replace function to replace the key
update table_1 set objects = regexp_replace(objects, '(\"name"+)', '"first name"');
update table_1 set objects = regexp_replace(objects, '(\"surname"+)', '"second name"')
Demo in dbfiddle

Update column with multiple values Postgres

Sample data:
I am trying update a column with values from multiple columns in another table if two columns match.
Consider the following query:
UPDATE application_table
SET asset_list = asset_table.asset_name
FROM asset_table
WHERE application_table.application_name = asset_table.applications;
My table structure is:
application_table:
"asset_list"; "text[]"
"application_name"; "character varying"
asset_table:
"asset_name"; "character varying"
"applications"; "character varying"
I get the following error:
ERROR: column "asset_list" is of type text[] but expression is of type character varying
Line 12 SET asset_list = asset_table.asset_name
What you need to do is aggregate the asset_name per applications value and set asset_list to that aggregated value.
Problem is you can't do something like
UPDATE ..
SET asset_list = ARRAY_AGG(asset_name)
FROM ...
because aggregate functions are not allowed in updates like that.
So here's two other ways to do it:
UPDATE app_table
SET asset_list = _asset_list
FROM (
SELECT applications, ARRAY_AGG(asset_name ORDER BY asset_name) AS _asset_list
FROM asset_table
GROUP BY applications
) AS a
WHERE app_name = applications;
https://www.db-fiddle.com/f/pKB5k6Lexwzqv6ZbCCdJay/0
This first builds a result set of distinct application names and an array of all the asset_names for each of the app names. Then it updates the table as usual with that array value.
Another way is:
UPDATE app_table
SET asset_list = (SELECT ARRAY_AGG(asset_name ORDER BY asset_name)
FROM asset_table
WHERE applications = app_name)
;
https://www.db-fiddle.com/f/8oVWsubXW93n142gtZYLXB/0
This will update every record in app_table, and calculates the array value on the fly for every record.

updatexml for particular rows only

Context: I want to increase the allowance value of some employees from £1875 to £7500, and update their balance to be £7500 minus whatever they have currently used.
My Update statement works for one employee at a time, but I need to update around 200 records, out of a table containing about 6000.
I am struggling to workout how to modify the below to update more than one record, but only the 200 records I need to update.
UPDATE employeeaccounts
SET xml = To_clob(Updatexml(Xmltype(xml),
'/EmployeeAccount/CurrentAllowance/text()',187500,
'/EmployeeAccount/AllowanceBalance/text()',
750000 - (SELECT Extractvalue(Xmltype(xml),
'/EmployeeAccount/AllowanceBalance',
'xmlns:ts=\"http://schemas.com/\", xmlns:xt=\"http://schemas.com\"'
)
FROM employeeaccounts
WHERE id = '123456')))
WHERE id = '123456'
Example of xml column (stored as clob) that I want to update. Table has column ID that hold PK of employees ID EG 123456
<EmployeeAccount>
<LastUpdated>2016-06-03T09:26:38+01:00</LastUpdated>
<MajorVersion>1</MajorVersion>
<MinorVersion>2</MinorVersion>
<EmployeeID>123456</EmployeeID>
<CurrencyID>GBP</CurrencyID>
<CurrentAllowance>187500</CurrentAllowance>
<AllowanceBalance>100000</AllowanceBalance>
<EarnedDiscount>0.0</EarnedDiscount>
<NormalDiscount>0.0</NormalDiscount>
<AccountCreditLimit>0</AccountCreditLimit>
<AccountBalance>0</AccountBalance>
</EmployeeAccount>
You don't need a subquery to get the old balance, you can use the value from the current row; which means you don't need to correlate that subquery and can just use an in() in the main statement:
UPDATE employeeaccounts
SET xml = To_clob(Updatexml(Xmltype(xml),
'/EmployeeAccount/CurrentAllowance/text()',187500,
'/EmployeeAccount/AllowanceBalance/text()',
750000 - Extractvalue(Xmltype(xml),
'/EmployeeAccount/AllowanceBalance',
'xmlns:ts=\"http://schemas.com/\", xmlns:xt=\"http://schemas.com\"')
))
WHERE id in (123456, 654321, ...);

PostgreSQL: check if attribute is in table

I'm writing some triggers to check if an arrtibute of a newly create tuple is present in another table. What is the best way to check this?
IF (SELECT * FROM TABLEB where NEW.Attribute = Attribute) = NULL THEN
return NULL
END IF
Is there a better way? And does a Select that returns nothing = NULL or empty set?
Use IF EXISTS (SELECT * FROM TABLEB where NEW.Attribute = Attribute).
An empty rowset isn't the same as NULL, which represents an empty cell of a row. Your syntax would only be valid if the query only selected one row, in which case PostgreSQL will allow use of comparison operators against the top cell returned, which counts as NULL if none are returned.

How to insert DB Default values under EF?

when adding a new record like this
ContentContacts c2 = new ContentContacts();
c2.updated_user = c2.created_user = loggedUserId;
c2.created_date = c2.updated_date = DateTime.UtcNow;
db.ContentContacts.AddObject(c2);
I'm getting
Cannot insert the value NULL into column 'main_email_support', table 'SQL2008R2.dbo.ContentContacts'; column does not allow nulls. INSERT fails. The statement has been terminated.
but the default value in the database is an empty string like:
why am I getting such error? shouldn't the EF says something like:
"ohh, it's a nullvalue, so let's add the column default value instead"
I did a small test, created a table with a column that had a default value but did not allow nulls.
Then this SQL Statement:
INSERT INTO [Test].[dbo].[Table_1]
([TestText])
VALUES
(null)
Gives this error:
Msg 515, Level 16, State 2, Line 1
Cannot insert the value NULL into column 'TestText', table
'Test.dbo.Table_1'; column does not allow nulls. INSERT fails.
The problem here is that the insert specifies all the columns, also those with default values. The the Insert tries to update the columns with null values.
You have 2 options:
Update the table through a view, which does not contain the default columns
Set the default values in your C# code
A default value is business logic, so there is a case for it being set in the business layer of your application.