I need to write a sp that will insert the characters after the first 4000 characters on the second line - sql

I have a column named 'Products' and its VARCHAR2(4000). In some cases I send more characters than 4000. It looks like '1,2,3,4,5,6...'. How can i insert first 4000 characters into one row and insert remaining to another row but of course it should consider the comma.
I tried to use array system but couldnt figure it out.

Don't use comma-demilited strings.
If you are going to store relational data then use another table.
If you are currently using:
CREATE TABLE main_table (
id NUMBER
GENERATED ALWAYS AS IDENTITY
PRIMARY KEY,
product_ids VARCHAR2(4000)
);
Then change it to:
CREATE TABLE main_table (
id NUMBER
GENERATED ALWAYS AS IDENTITY
PRIMARY KEY
);
CREATE TABLE main_table_products (
id REFERENCES main_table (id),
product_id NUMBER
-- Assuming you have a products table
REFERENCES products (id),
CONSTRAINT main_table_products__pk PRIMARY KEY (id, product_id)
);
Then you know:
The product_ids are all the correct data type,
You have referential constraints insuring that the product_ids are valid products.
You do not have duplicate product_ids for each id as the primary key prevents it.
You can insert any number of product_ids.
You can easily delete or update product_ids.
If you use a delimited VARCHAR2 string then you do not (out-of-the-box) have any of those benefits.

Related

Constraint on a group of rows

For a simple example, let's say I have a list table and a list_entry table:
CREATE TABLE list
(
id SERIAL PRIMARY KEY,
);
CREATE TABLE list_entry
(
id SERIAL PRIMARY KEY,
list_id INTEGER NOT NULL
REFERENCES list(id)
ON DELETE CASCADE,
position INTEGER NOT NULL,
value TEXT NOT NULL,
CONSTRAINT list_entry__position_in_list_unique
UNIQUE(list_id, position)
);
I now want to add the following constraint: all list entries with the same list_id have position entries that form a contiguous sequence starting at 1.
And I have no idea how.
I first thought about EXCLUDE constraints, but that seems to lead nowhere.
Could of course create a trigger, but I'd prefer not to, if at all possible.
You can't do that with a constraint - you would need to implement the logic in code (e.g. using triggers, stored procedures, application code, etc.)
I'm not aware of such way to use constraints. Normally a trigger would be the most straightforward choice, but in case you want to avoid using them, try to get the current position number for the list_entry with the list_id you're about to insert, e.g. inserting a list_entry with list_id = 1:
INSERT INTO list_entry (list_id,position,value) VALUES
(1,(SELECT coalesce(max(position),0)+1 FROM list_entry WHERE list_id = 1),42);
Demo: db<>fiddle
You can use a generated column to reference the previous number in the list, essentially building a linked list. This works in Postgres:
create table list_entry
(
pos integer not null primary key,
val text not null,
prev_pos integer not null
references list_entry (pos)
generated always as (greatest(0, pos-1)) stored
);
In this implementation, the first item (pos=0) points to itself.

Creating unique primary key to ignore duplicates

I have a main large table which I have had to put into 3rd normal form and into smaller tables (with primary and foreign keys linking them). The table is about renting books.
I have a customer table which I need to create a primary key for. In the main large table there are duplicates of the customer_id, as the table as a whole is for renting the books, so one customer may have more than one renting.
The table I am currently trying to add a primary key for will not have any nulls or duplicates, however i am unsure how to create the primary key for this without the error- unsure how to make it unique.
CREATE TABLE customer AS
SELECT cust_id, country_id, name, address, postcode
FROM BOOKS
WHERE cust_id != 0;
ALTER TABLE customer
ADD PRIMARY KEY (cust_id);
Is anyone able to help me in how to create the primary key on my customer table, but just taking each unique cust_id from the main table.
In SQL Server the straightforward way to add unique keys is to use IDENTITY. Identity fields are integer fields that auto populate successive values by a specified start value and interval. If you don't specify the interval it will start at 1 and increase the value by 1 each time a value is assigned.
While it's usually done when creating a table, you can do it in your ALTER TABLE step, and it will assign values when added to an existing table. I've explicitly specified the start value and interval that matches the default to show the syntax :
ALTER TABLE customer
ADD cust_id int not null PRIMARY KEY IDENTITY(1,1)

Primary key without duplicated values

i'm trying and success to create primary key in Redshif
create table my_table(id int ,
primary key(id));
insert into my_table values
(id),
(1),
(1),
(20);
select count(*) from my_table
3
but it allows me to upload duplicated value ,
as far as i know primary key should contain unique values ,
did i do something wrong?
you can find your answer here
How to create an Index in Amazon Redshift
one of the answers mention your problem with the primary key
Create an identity key which will act as an auto_increment surrogate key. This'll serve both the purpose - to uniquely identify the records in the table and prevent insertion of duplicate values.
Let's create a dummy table:
create table scratchpad.test_1
(id bigint identity(1,1),
name varchar(10));
insert into scratchpad.test_1(name)
values
('a'),('b'),('c'),('d');
select * from scratchpad.test_1;
The id column acts as a primary key. Deleting any record from the table does not impact the sequencing of other values and the id column can be used to uniquely identify the subsequent row.

Add serial value across multiple tables

I have the following two tables in my Postgres database:
CREATE TABLE User (
Id serial UNIQUE NOT NULL,
Login varchar(80) UNIQUE NOT NULL,
PRIMARY KEY (Id,Login)
);
CREATE TABLE UserData (
Id serial PRIMARY KEY REFERENCES Users (Id),
Password varchar(255) NOT NULL
);
Say, I add a new user with INSERT INTO Users(Id, Login) VALUES(DEFAULT, 'John') and also want to add VALUES(id, 'john1980') in UserData where id is John's new id.
How do I get that id? Running a query for something just freshly created seems superfluous. I have multiple such situations across the database. Maybe my design is flawed in general?
(I'm obviously not storing passwords like that.)
1) Fix your design
CREATE TABLE usr (
usr_id serial PRIMARY KEY,
,login text UNIQUE NOT NULL
);
CREATE TABLE userdata (
usr_id int PRIMARY KEY REFERENCES usr
,password text NOT NULL
);
Start by reading the manual about identifiers and key words.
user is a reserved word. Never use it as identifier.
Use descriptive identifiers. id is useless.
Avoid mixed case identifiers.
serial is meant for a unique column that can be pk on its own. No need for a multicolumn pk.
The referencing column userdata.usr_id cannot be a serial, too. Use a plain integer.
I am just using text instead of varchar(n), that's optional. More here.
You might consider to merge the two tables into one ...
2) Query to INSERT in both
Key is the RETURNING clause available for INSERT, UPDATE, DELETE, to return values from the current row immediately.
Best use in a data-modifying CTE:
WITH ins1 AS (
INSERT INTO usr(login)
VALUES ('John') -- just omit default columns
RETURNING usr_id -- return automatically generated usr_id
)
INSERT INTO userdata (usr_id, password )
SELECT i.usr_id, 'john1980'
FROM ins1 i;
You can consider using a trigger. The Id column of the newly inserted row can be accessed by the name NEW.Id.
References:
CREATE TRIGGER documentation on PostgreSQL Manual
Trigger Procedures

The ALTER TABLE statement conflicted with the FOREIGN KEY constraint

Why does add a foreign key to the tblDomare table result in this error?
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint "FK__tblDomare__PersN__5F7E2DAC". The conflict occurred in database "almu0004", table "dbo.tblBana", column 'BanNR'.
Code
CREATE TABLE tblDomare
(PersNR VARCHAR (15) NOT NULL,
fNamn VARCHAR (15) NOT NULL,
eNamn VARCHAR (20) NOT NULL,
Erfarenhet VARCHAR (5),
PRIMARY KEY (PersNR));
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (7606091347,'Josefin','Backman',4);
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (8508284163,'Johanna','Backman',1);
CREATE TABLE tblBana
(BanNR VARCHAR (15) NOT NULL,
PRIMARY KEY (BanNR));
INSERT INTO tblBana (BanNR)
Values (1);
INSERT INTO tblBana (BanNR)
Values (2);
INSERT INTO tblBana (BanNR)
Values (3);
ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);
It occurred because you tried to create a foreign key from tblDomare.PersNR to tblBana.BanNR but/and the values in tblDomare.PersNR didn't match with any of the values in tblBana.BanNR. You cannot create a relation which violates referential integrity.
This query was very useful for me. It shows all values that don't have any matches
select FK_column from FK_table
WHERE FK_column NOT IN
(SELECT PK_column from PK_table)
Try this solution:
There is a data item in your table whose associated value doesn't exist in the table you want to use it as a primary key table.
Make your table empty or add the associated value to the second table.
It is possible to create the foreign key using ALTER TABLE tablename WITH NOCHECK ..., which will allow data that violates the foreign key.
"ALTER TABLE tablename WITH NOCHECK ..." option to add the FK -- This solution worked for me.
Remove all existing data from your tables and then make a relation between the tables.
Before You add Foreign key to the table, do the following
Make sure the table must empty or The column data should match.
Make sure it is not null.
If the table contains do not go to design and change, do it manually.
alter table Table 1 add foreign key (Column Name) references Table 2 (Column Name)
alter table Table 1 alter column Column Name attribute not null
I guess, a column value in a foreign key table should match with the column value of the primary key table. If we are trying to create a foreign key constraint between two tables where the value inside one column(going to be the foreign key) is different from the column value of the primary key table then it will throw the message.
So it is always recommended to insert only those values in the Foreign key column which are present in the Primary key table column.
For ex. If the Primary table column has values 1, 2, 3 and in Foreign key column the values inserted are different, then the query would not be executed as it expects the values to be between 1 & 3.
In very simple words your table already has data present in it and the table you are trying to create relationship with does have that Primary key set for the values that are already present.
Either delete all the values of the existing table.
Add all the values of foreign key reference in the new table.
Try DELETE the current datas from tblDomare.PersNR . Because the values in tblDomare.PersNR didn't match with any of the values in tblBana.BanNR.
When you define a Foreign Key in table B referencing the Primary Key of table A it means that when a value is in B, it must be in A. This is to prevent unconsistent modifications to the tables.
In your example, your tables contain:
tblDomare with PRIMARY KEY (PersNR):
PersNR |fNamn |eNamn |Erfarenhet
-----------|----------|-----------|----------
6811034679 |'Bengt' |'Carlberg' |10
7606091347 |'Josefin' |'Backman' |4
8508284163 |'Johanna' |'Backman' |1
---------------------------------------------
tblBana:
BanNR
-----
1
2
3
-----
This statement:
ALTER TABLE tblDomare
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);
says that any line in tblDomare with key PersNR must have a correspondence in table tblBana on key BanNR. Your error is because you have lines inserted in tblDomare with no correspondence in tblBana.
2 solutions to fix your issue:
either add lines in tblBana with BanNR in (6811034679, 7606091347, 8508284163)
or remove all lines in tblDomare that have no correspondence in tblBana (but your table would be empty)
General advice: you should have the Foreign Key constraint before populating the tables. Foreign keys are here to prevent the user of the table from filling the tables with inconsistencies.
i had this error too
as Smutje reffered make sure that you have not a value in foreign key column of your base foreign key table that is not in your reference table i.e(every value in your base foreign key table(value of a column that is foreign key) must also be in your reference table column)
its good to empty your base foreign key table first then set foreign keys
the data you have entered a table(tbldomare) aren't match a data you have assigned primary key table. write between tbldomare and add this word (with nocheck) then execute your code.
for example you entered a table tbldomar this data
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet)
Values (6811034679,'Bengt','Carlberg',10);
and you assigned a foreign key table to accept only 1,2,3.
you have two solutions one is delete the data you have entered a table then execute the code. another is write this word (with nocheck) put it between your table name and add
like this
ALTER TABLE tblDomare with nocheck
ADD FOREIGN KEY (PersNR)
REFERENCES tblBana(BanNR);
Smutje is correct and Chad HedgeCock offered a great layman's example.
Id like to build on Chad's example by offering a way to find/delete those records.
We will use Customer as the Parent and Order as the child. CustomerId is the common field.
select * from Order Child
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null
if you are reading this thread... you will get results. These are orphaned children. select * from Order Child
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null Note the row count in the bottom right.
Go verify w/ whomever you need to that you are going to delete these rows!
begin tran
delete Order
from Order Child
left join Customer Parent on Child.CustomerId = Parent.CustomerId
where Parent.CustomerId is null
Run the first bit.
Check that row count = what you expected
commit the tran
commit tran
Be careful. Someone's sloppy programming got you into this mess. Make sure you understand the why before you delete the orphans. Maybe the parent needs to be restored.
From our end, this is the scenario:
We have an existing table in the database with records.
Then I introduces a NOT nullable foreign key
After executing the update i got this error.
How did i solve you ask?
SOLUTION: I just removed all the records of the table, then tried to update the database and it was successful.
This happens to me, since I am designing my database, I notice that I change my seed on my main table, now the relational table has no foreign key on the main table.
So I need to truncate both tables, and it now works!
You should see if your tables has any data on the rows. If "yes" then you should truncate the table(s) or else you can make them to have the same number of data at tblDomare.PersNR to tblBana.BanNR and vise-verse.
In my scenario, using EF, upon trying to create this new Foreign Key on existing data, I was wrongly trying to populate the data (make the links) AFTER creating the foreign key.
The fix is to populate your data before creating the foreign key since it checks all of them to see if the links are indeed valid. So it couldn't possibly work if you haven't populated it yet.
I encounter some issue in my project.
In child table, there isn't any record Id equals 1 and 11
I inserted DEAL_ITEM_THIRD_PARTY_PO table which Id equals 1 and 11 then I can create FK
Please first delete data from that table and then run the migration again. You will get success
I had the same problem.
My issue was having nullable: true in column (migration file):
AddColumn("dbo.table", "column", c => c.Int(nullable: true));
Possible Solutions:
Change nullable 'false' to 'true'. (Not Recommended)
Change property type from int to int? (Recommended)
And if required, change this later after adding column > then missing field data in previous records
If you've changed an existing property from nullable to non-nullable:
3) Fill the column data in database records
A foreign key constraint in a child table must have a parent table with a primary key. The primary key must be unique. The foreign key value must match a value in the patent table primary key
When you alter table column from nullable to not nullable column where this column is foreign key, you must :
Firstly, initialize this column with value (because it is foreign
key not nullable).
After that you can alter your table column normally.
Please try below query:
CREATE TABLE tblBana
(BanNR VARCHAR (15) NOT NULL PRIMARY KEY,
);
CREATE TABLE tblDomare
(PersNR VARCHAR (15) NOT NULL PRIMARY KEY,
fNamn VARCHAR (15) NOT NULL,
eNamn VARCHAR (20) NOT NULL,
Erfarenhet VARCHAR (5),
FK_tblBana_Id VARCHAR (15) references tblBana (BanNR)
);
INSERT INTO tblBana (BanNR)
Values (3);
INSERT INTO tblDomare (PersNR,fNamn,eNamn,Erfarenhet,FK_tblBana_Id)
Values (8508284173,'Johanna','Backman',1,3);
or you can use this
SELECT fk_id FROM dbo.tableA
Except
SELECT fk_id From dbo.tableB
and just FYI, in case you do all of your data reference checks and find no bad data...apparently it is not possible to create a foreign key constraint between two tables and fields where those fields are the primary key in both tables! Do not ask me how I know this.