Postgresql generated column fails when concating not null columns - sql

I have this table definition in pgAdmin4:
CREATE TABLE IF NOT EXISTS cdr_event
(
id bigint primary key generated always as identity,
start_time timestamptz NOT NULL DEFAULT now(),
end_time timestamptz NULL,
group_id VARCHAR(10) NOT NULL,
environment VARCHAR(10) NOT NULL,
level VARCHAR(10) NOT NULL,
schema VARCHAR(30) NOT NULL,
instance INTEGER NOT NULL,
hive_instance_db_name VARCHAR(100) GENERATED ALWAYS AS (group_id||'_'||environment||'_'||level||'_'||schema||'_'||instance) STORED,
hive_static_db_name VARCHAR(100) GENERATED ALWAYS AS (group_id||'_'||environment||'_'||level||'_'||schema) STORED,
);
this fails with
ERROR: generation expression is not immutable
SQL state: 42P17
Why does postgres consider the concat mutable when the dependent columns are all NOT NULL? This thread suggests it should work
Is there anyway to create a concat-ed generated column without creating a custom concat function?
Thanks

Try keeping the involved columns of the same type, e.g. casting instance to text should do the trick:
CREATE TABLE IF NOT EXISTS cdr_event
(
id bigint primary key generated always as identity,
start_time timestamptz NOT NULL DEFAULT now(),
end_time timestamptz NULL,
group_id VARCHAR(10) NOT NULL,
environment VARCHAR(10) NOT NULL,
level VARCHAR(10) NOT NULL,
schema VARCHAR(30) NOT NULL,
instance INTEGER NOT NULL,
hive_instance_db_name VARCHAR(100) GENERATED ALWAYS AS (group_id||'_'||environment||'_'||level||'_'||schema||'_'||instance::text) STORED,
hive_static_db_name VARCHAR(100) GENERATED ALWAYS AS (group_id||'_'||environment||'_'||level||'_'||schema) STORED
);
Consider using text instead of varchar.
Demo: db<>fiddle

Related

Alternative to Postgresql BIGSERIAL data type in Azure Database?

I am learning Azure and data analytics with Azure. Recently finished learning Postgresql.
My question is if there is an alternative to BIGSERIAL data type for Azure Databases. I ran the query (below the error in the following) and had an error. Note that this datatype exists in Postgresql and hence I am getting confused in Azure. Any alternative to BIGSERIAL?
Failed to execute the query. Error: Column, parameter, or variable #1:
Cannot find data type BIGSERIAL.
create table person (
ID BIGSERIAL NOT NULL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(50),
gender VARCHAR(50) NOT NULL,
date_of_birth DATE NOT NULL,
Country_of_birth VARCHAR(50) NOT NULL
);
In PostgreSQL, the SERIAL keyword is used to setup an auto increment column, this works similar to auto increment in SQL. BIGSERIAL is an auto-incremented Bigint column of 8 bytes.
Closest, I could find "bigserial"in MS docs is as here
So...you can use BIGINT instead, below works fins for me.
create table person (
ID BIGINT NOT NULL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(50),
gender VARCHAR(50) NOT NULL,
date_of_birth DATE NOT NULL,
Country_of_birth VARCHAR(50) NOT NULL
);

SQLAlchemy Query Not Returning Same Value As Database

I am working on a project displays research opportunities and lets students signup to participate in them. When registering for a study, the server checks to see if the user is already in another time slot of the same study (not allowed).
The SQLAlchemy code is as follows:
same_study = db.session.query(db.func.count(['*'])) \
.filter(Research.research_id == ResearchSlot.research_id) \
.filter(ResearchSlot.research_slot_id == StudentResearch.research_slot_id) \
.filter(StudentResearch.user_id == Users.user_id) \
.filter(StudentResearch.student_research_id == slot_id) \
.filter(Users.user_email == user_email) \
.scalar()
In this, slot_id and user_email are variables. When this query runs (and I output the query being run) it looks like this:
SELECT count(*)
FROM Research, ResearchSlot, StudentResearch, Users
WHERE Research.ResearchID = ResearchSlot.ResearchID
AND ResearchSlot.ResearchSlotID = StudentResearch.ResearchSlotID
AND StudentResearch.UserID = Users.UserID
AND StudentResearch.StudentResearchID = 10
AND Users.UserEmail = "foo#bar.com"
The issue is, when the query is executed during use of the website, the query returns 0 (meaning they are not in another instance of the same research study) when it should be returning 1 (because they are in another instance). When I manually execute this query from the MySQL workbench it returns 1 as expected. Why the difference?
CREATE TABLE Users (
UserID BIGINT NOT NULL AUTO_INCREMENT,
UserEmail VARCHAR(100) NOT NULL,
UserPWHash VARCHAR(64) NOT NULL,
UserSalt VARCHAR(64) NOT NULL,
UserRole BIGINT NOT NULL,
UserPsychMajor BOOLEAN NOT NULL,
UserPsychMinor BOOLEAN NOT NULL,
CreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (UserID),
FOREIGN KEY (UserRole) REFERENCES Role(RoleID)
);
CREATE TABLE Research (
ResearchID BIGINT NOT NULL AUTO_INCREMENT,
ResearchName VARCHAR(100) NOT NULL,
ResearchFacilitator BIGINT NOT NULL,
ResearchDescription VARCHAR(500) NOT NULL,
ResearchCredits INT NOT NULL,
IsVisible BOOLEAN DEFAULT TRUE NOT NULL,
IsDeleted BOOLEAN DEFAULT FALSE NOT NULL,
CreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (ResearchID),
FOREIGN KEY (ResearchFacilitator) REFERENCES Users(UserID)
);
CREATE TABLE ResearchSlot (
ResearchSlotID BIGINT NOT NULL AUTO_INCREMENT,
ResearchID BIGINT NOT NULL,
ResearchSlotOpenings INT NOT NULL,
StartTime DATETIME NOT NULL,
EndTime DATETIME NOT NULL,
CreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (ResearchSlotID),
FOREIGN KEY (ResearchID) REFERENCES Research(ResearchID)
);
CREATE TABLE StudentResearch (
StudentResearchID BIGINT NOT NULL AUTO_INCREMENT,
UserID BIGINT NOT NULL,
ResearchSlotID BIGINT NOT NULL,
IsCompleted BOOLEAN DEFAULT FALSE NOT NULL,
CreatedOn DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (StudentResearchID),
FOREIGN KEY (UserID) REFERENCES Users(UserID),
FOREIGN KEY (ResearchSlotID) REFERENCES ResearchSlot(ResearchSlotID)
);
After trying a bunch of SQL-related things suggested above, I found out it had nothing to do with the actual statement or information. The problem was with logic in a different part of the server.

Create Table - Time Statement

I am having trouble trying to create a table using MS Access.
I know for sure my problem lies in the "datetime" field but I can not figure what I am missing or doing wrong.
When I click "run" I get the
"Syntax Error in Field Definition"
Create Table Appointments
(DocID char(4) not null primary key,
PatID char(8) not null,
Day varchar(8) not null,
Time datetime not null,
Procedure varchar(50) null);
Time and procedure are reserved words, and therefore should be escaped:
Create Table Appointments
(DocID char(4) not null primary key,
PatID char(8) not null,
[Day] varchar(8) not null,
[Time] datetime not null,
[Procedure] varchar(50) null);
Or better yet, find names that aren't reserved words:
Create Table Appointments
(DocID char(4) not null primary key,
PatID char(8) not null,
AppointmentDay varchar(8) not null,
AppointmentTime datetime not null,
MedicalProcedure varchar(50) null);
Here Procedure and Time are reserved words and so need to be escaped using [] like below. See Documentation for more information
Create Table Appointments
(DocID char(4) not null primary key,
PatID char(8) not null,
[Day] varchar(8) not null,
[Time] datetime not null,
[Procedure] varchar(50) null);
As Time & Procedure are reserved keyword, so wrap Time & Procedure column in brackets [] or choose alternate names, if possible. See List of Keyword
[Time] and [Procedure]

How to Sql defined function as columns e.g User_Id int when creating tables [duplicate]

I am creating tables in Sql Management Studio 2012 using SQL. How do I make fields or columns with names that are already defined in Sql Server e.g User_ID, User_Name. I want to use them as fields in my tables.
Table definition from Duplicate Post:
create table Ticket(
Ticket_Id varchar(10) not null,
TicketType_Id varchar(3) not null,
Ticket_PurchaseDate DateTime null,
LottoDraw_Id int null,
User_Id int null,
Ticket_IsWinner bit null
Primary Key(Ticket_Id,TicketType_Id)
)
Warp the column name like in brackets [ ] ... such as
create table Ticket(
Ticket_Id varchar(10) not null,
TicketType_Id varchar(3) not null,
Ticket_PurchaseDate DateTime null,
LottoDraw_Id int null,
[User_Id] int null,
Ticket_IsWinner bit null
Primary Key(Ticket_Id,TicketType_Id)
)

SQL server 2012 tables issue, sysdate and to_date issue

I have two issues while trying to create tables.
For **sysdate*** it says invalid column name
for *TO_DATE('01-JAN-2008','DD-MON-YYYY')));* it says TO_DATE is not a reconigized built-in function name.
^ both are in the Table Invoice.
This is using SQL SERVER 2012
CREATE TABLE VENDOR(
V_CODE INTEGER NOT NULL UNIQUE,
V_NAME VARCHAR(35) NOT NULL,
V_CONTACT VARCHAR(15) NOT NULL,
V_AREACODE CHAR(3) NOT NULL,
V_PHONE CHAR(8) NOT NULL,
V_STATE CHAR(2) NOT NULL,
v_ORDER CHAR(1) NOT NULL,
PRIMARY KEY (V_CODE));
CREATE TABLE PRODUCT(
P_CODE VARCHAR(10) NOT NULL,
P_DESCRIPT VARCHAR(35) NOT NULL,
P_INDATE DATE NOT NULL,
P_QOH SMALLINT NOT NULL,
P_MIN SMALLINT NOT NULL,
P_PRICE DECIMAL(8,2) NOT NULL,
P_DISCOUNT DECIMAL(5,2) NOT NULL,
V_CODE INTEGER,
PRIMARY KEY (P_CODE),
FOREIGN KEY(V_CODE) REFERENCES VENDOR ON UPDATE CASCADE);
CREATE TABLE CUSTOMER(
CUS_CODE DECIMAL PRIMARY KEY,
CUS_LNAME VARCHAR(15) NOT NULL,
CUS_FNAME VARCHAR(15) NOT NULL,
CUS_INITIAL CHAR(1),
CUS_AREACODE CHAR(3) DEFAULT '615' NOT NULL,
CHECK(CUS_AREACODE IN ('615','713','931')),
CUS_PHONE CHAR(8) NOT NULL,
CUS_BALANCE DECIMAL(9,2) DEFAULT 0.00,
CONSTRAINT CUS_UI1 UNIQUE (CUS_LNAME, CUS_FNAME));
CREATE TABLE INVOICE (
INV_NUMBER DECIMAL PRIMARY KEY,
CUS_CODE DECIMAL NOT NULL REFERENCES CUSTOMER(CUS_CODE),
INV_DATE DATE DEFAULT SYSDATE NOT NULL,
CONSTRAINT INV_CK1 CHECK (INV_DATE > TO_DATE('01-JAN-2008','DD-MON-YYYY')));
You have two issues:
the function to get the current system date and time is called SYSDATETIME() in T-SQL/SQL Server (not sysdate)
the way to convert a string to a date or datetime in T-SQL/SQL Server is using CAST or CONVERT (not TO_DATE - there is no such function in T-SQL)
Use something like
SELECT CAST('01-JAN-2008' AS DATE)
or something like that (it's highly dependent on your language/date format settings in SQL Server whether it'll work or not). If you need to specify a specific format, you can use CONVERT which allows you to use one of the many predefined formats (see relevant details in the MSDN documentation).
If that's still not enough - SQL Server 2012 has a new function called PARSE which allows you to specify any arbitrary date format that your string is formatted in. Again, see the relevant MSDN documentation for details.
The best thing is to avoid converting dates back and forth to and from strings if ever possible, and in your case, this should be easily doable! Just use:
INV_DATE DATE DEFAULT SYSDATETIME() NOT NULL,
CONSTRAINT INV_CK1 CHECK (INV_DATE > '20080101');