I have 2 tables recording company market data.
A table recording stock market symbols
CREATE TABLE appl.symbols (
id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
symbol VARCHAR(10) NOT NULL,
exchange VARCHAR(10) NOT NULL,
date_added DATE NOT NULL DEFAULT CURRENT_DATE,
active BOOLEAN NOT NULL DEFAULT true,
)
And a table with many columns (about 50) recording details about the company.
CREATE TABLE appl.fundamentals_overview (
overview_id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
symbol_id INT,
CONSTRAINT fk_symbol
FOREIGN KEY(symbol_id)
REFERENCES appl.symbols(id),
assettype VARCHAR(255),
name VARCHAR(255),
description VARCHAR(1500),
cik VARCHAR(10),
currency VARCHAR(10),
country VARCHAR(10),
sector VARCHAR(50),
industry VARCHAR(100),
address VARCHAR(100),
fiscalyearend VARCHAR(10),
latestquarter DATE,
marketcapitalization BIGINT,
ebitda BIGINT,
peratio NUMERIC(20, 4),
pegratio NUMERIC(20, 4),
bookvalue NUMERIC(20, 4),
dividendpershare NUMERIC(20, 4),
dividendyield NUMERIC(20, 4),
eps NUMERIC(20, 4),
revenuepersharettm NUMERIC(20, 4),
profitmargin NUMERIC(20, 4),
operatingmarginttm NUMERIC(20, 4)
... many more columns
)
I am trying to allow client code to create a row without needing to know unique IDs, and not needing to give a value for all columns. Something like the following needs to be valid (as long as they know the symbol name):
{"assettype": "Common Stock",
"name": "AcmeINC",
"cik": "1555752",
"currency": "USD",
"country": "USA",
"fiscalyearend": "December",
"peratio": 235.56
}
I created a function, but I can not work out how to get the column names, in the right order, and then specify a variable for the column names. This is as far as I got
CREATE OR REPLACE FUNCTION appl.insert_fund_overview(sym TEXT, ex TEXT, js TEXT) RETURNS VOID AS
$func$
DECLARE
symID BIGINT := 0;
fullJSON JSON;
tempJSON JSON;
colNames TEXT;
BEGIN
symID := (SELECT appl.symbols.id FROM appl.symbols WHERE symbol = sym AND exchange = ex);
tempJSON := json_build_object('symbol_id', symID);
fullJSON := (js::jsonb) || (tempJSON::jsonb);
colNames := (SELECT string_agg(elem, ',') FROM json_object_keys(fullJSON) elem);
--The value of colNames contains the JSON key names, but in wrong order
-- This does not work
INSERT INTO appl.fundamentals_overview (colNames)
SELECT *
FROM json_populate_record(NULL::appl.fundamentals_overview, fullJSON::json);
END
$func$ LANGUAGE plpgsql;
ERROR: column "colnames" of relation "fundamentals_overview" does not exist
json_populate_record()
will generate a row with all columns anyway. so you can just leave out the(colnames)
part completelyjson
andjsonb
(exploiting side effects)? Or just by accident? Please always disclose your version of Postgres.