I have a legacy VB application that we are maintaining. A design decision we took was to store certain data points as concatenated strings. This change is set in stone as the majority of code is complete.
I'm running a loop through an array of values. What I'm doing is, looking up a LABEL for each value in a reference table. I need to be able to display the values in one label. I'm having a difficult time concetenating the values into a string and then displaying it in a label. Here is my code...
If strField = "Expenditures" Then
If InStr(1, strOldValue, ",") > 0 Then
strArray = Split((strOldValue), ",")
For x = 0 To UBound(strArray)
For Each item In strArray
strMessage = DLookUp(1, "Label", "tblText_References", "ID = '" & item & "'
**''''******here I'm trying to save teh value in strMessage, however, at next item, I need it to be added to strMessage in some fashion, with a (,), I'm not sure how to do it. There are anywhere from 2 to 4 ITEMS i might have.**
Next item
Next
End if
End if
You should definitely reconsider how you are storing the meal data. Never store multiple values in a single column concatenated by commas. Instead, you want to create a table to contain the selected items, which can then be JOINed to other tables, utilizing a one-to-many relationship.
The following code shows an example of how you might accomplish this.
Create a table to contain Users who will have Meals associated with them:
CREATE TABLE dbo.Users
(
UserID INT NOT NULL
CONSTRAINT PK_Users
PRIMARY KEY CLUSTERED
, UserName VARCHAR(255) NOT NULL
);
Create a table to describe the Meals:
CREATE TABLE dbo.Meals
(
MealID INT NOT NULL
CONSTRAINT PK_Meals
PRIMARY KEY CLUSTERED
, MealName VARCHAR(255) NOT NULL
);
Create a junction table that joins the Users to their Meals:
CREATE TABLE dbo.UserMeals
(
UserID INT NOT NULL
, MealID INT NOT NULL
, CONSTRAINT PK_UserMeals
PRIMARY KEY CLUSTERED (UserID, MealID)
);
Insert a sample user:
INSERT INTO dbo.Users (UserID, UserName)
VALUES (1, 'Test User');
Insert the 4 meals:
INSERT INTO dbo.Meals (MealID, MealName)
VALUES (80, 'Breakfast')
, (81, 'Lunch')
, (82, 'Dinner')
, (83, 'Snack');
Insert some sample rows into the UserMeals table that associate meals with users:
INSERT INTO dbo.UserMeals (UserID, MealID)
VALUES (1, 80)
, (1, 81);
Show the users with their associated meals:
SELECT u.UserName
, m.MealName
FROM dbo.UserMeals um
INNER JOIN dbo.Users u ON um.UserID = u.UserID
INNER JOIN dbo.Meals m ON um.MealID = m.MealID;
The results:
this is all the code that's needed. I created a new variable called strNEWmessage as string. I already had a variable called strMessage as string The answer is: strNewMessage = strNewMessage & "," strMessage
Related
I need to create a sequence in the database that cannot be using sequence or identity.
There is a table in the database called File where all the files that users send in different areas of the system are stored.
It contains the id (primary key), name, type, folder, number, hash...
CREATE TABLE dbo.[File]
(
FileId uniqueidentifier NOT NULL,
Name nvarchar(30) NOT NULL,
FileTypeId int NOT NULL,
FileFolderId int NOT NULL,
Number int NOT NULL,
Hash nvarchar(50) NOT NULL
...
) ON [PRIMARY]
And then for each feature there is a table expanding the properties of the File table, an example is ContractFile.
It has the same id of the File table and with a few more fields and the id of the Contract table, creating the relation.
CREATE TABLE dbo.ContractFile
(
FileId uniqueidentifier NOT NULL,
ContractId uniqueidentifier NOT NULL
...
) ON [PRIMARY]
So the filename should follow a pattern.
050#H4G5H4G244#001.pdf
050#H4G5H4G244#002.pdf
060#H4G5H4G244#001.pdf
The first 3 digits is a code that is in the FileType table.
The digits in the middle is the code in the Contract table.
And the last 3 is the sequence that was inserted.
Then it groups the string by the FileType and the Contract.
So I created a trigger in the ContractFile table for when inserting it get the biggest number for that FileType and for the Contract and add +1, setting the Number field of the File table.
Then the file name is updated (in the same trigger)
CREATE TRIGGER [dbo].[tgContractFileInsert]
ON [dbo].[ContractFile]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON
UPDATE dbo.File
SET Number = COALESCE(
(SELECT MAX(AR.Number)
FROM dbo.ContractFile NOA
INNER JOIN dbo.File AR
ON AR.FileId = NOA.FileId
WHERE NOA.ContractId = I.ContractId AND
AR.FileTypeId = T.FileTypeId
),
0) + 1
FROM dbo.File T WITH (XLOCK)
INNER JOIN Inserted I
ON I.FileId = T.FileId
WHERE T.Number IS NULL
UPDATE dbo.File
SET Name = dbo.fnFileName(AP.Code, NOB.Code, T.Numero, T.Name)
FROM dbo.File T
INNER JOIN Inserted I
ON I.FileId = T.FileId
INNER JOIN dbo.FileType AP
ON AP.FileTypeId = T.FileTypeId
INNER JOIN dbo.Contract NOB
ON NOB.ContractId = I.ContractId
END
At first it works, but when we have a large volume being inserted, there is a deadlock.
And from what I'm seeing also when inserting more than one record will end up getting the same number, since the Inserted table will bring two records and the +1 is not checking this.
How could I solve this? What is the best way?
Avoid deadlock, will the sequence be correct even inserting more than one record at a time and have a good performance?
I am attempting to write data into two tables, let's say:
Primary_Tbl(Id, Title)
Foreign_Tbl(Id, Primary_Tbl_id, Subtext)
I want to insert the data in both of these tables but also want to maintain primary keys and foreign keys relationship. The issue is that I won't have primary keys until data is inserted in Primary_Tbl that can be used to insert in Foreign_Tbl.Primary_Tbl_id
Is there any clean and neat approach to achieve this in Snowflake?
You can insert into 2 tables at the same time with insert all, while using sequences to generate ids:
create or replace sequence seq_01 start = 1 increment = 1;
create or replace sequence seq_02 start = 1000 increment = 1;
create or replace table table_a (id integer, title string);
create or replace table table_b (id integer, a_id integer, subtext string);
insert all
into table_a values(id_a, title)
into table_b values(id_b, id_a, subtext)
select seq_01.nextval id_a, seq_02.nextval id_b
, 'a title' title, 'the subtext' subtext
;
select *
from table_a a
join table_b b
on a.id=b.a_id;
I need to add a constraint to validate that number of rows referencing master table is lower than value in master row, e.g we have a table
master(master_id int pk, max_val int) and slave(slave_id int pk, master_id fk ref master(master_id)) (so slave is de facto a colection of something), and I want that count(master_id) in slave is <= than max_val for this master_id. I have a constraint
constraint NO_MORE_PASS check ((select count(head_id) from parts p where
p.head_id = head_id) <= (select max_val from head where id = head_id));
(not sure if it is correct, however SQL Server tells that subqueries are not allowed (sql server 2017) so...).
I have also read Check Constraint - Subqueries are not allowed in this context, so the question: is there any other alternative (I would like to avoid using trigger)?.
I'am using this in spring app with spring data jpa (and hibernate) - may be useful, but would like to make it on db side rather than in the app.
Nethertheless entity it is like:
#Entity
#Table(name = "route_parts")
data class RoutePart(
#Id
#Column(name = "route_part_id")
#GeneratedValue(strategy = GenerationType.AUTO)
var id: Long? = null,
//...
#Column(nullable = false)
var slots: Int? = null,
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name = "route_part_passengers",
joinColumns = [(JoinColumn(name = "route_part_id"))],
inverseJoinColumns = [(JoinColumn(name = "user_id"))]
)
var passengers: Set<ApplicationUser> = setOf()
)
and in that case ApplicationUser is a slave (or better - another table will be created, and actually this will be that slave table) limited by slots value.
So the question is...
How can I achieve limiting number of ApplicationUser attached to each RoutePart
If you want your check constraints to be based on queries, you must use a user defined function for the check constraint to work with.
Here is a quick example:
Tables:
CREATE TABLE dbo.Parent
(
Id int,
MaxNumberOfChildren int NOT NULL
);
CREATE TABLE dbo.Child
(
Id int,
ParentId int
);
User defined function (All it does is return the difference between the MaxNumberOfChildren and the number of records in the Child table with the same ParentId):
CREATE FUNCTION dbo.RestrictNumbrOfChildren
(
#ParentId int
)
RETURNS int
AS
BEGIN
RETURN
(
SELECT MaxNumberOfChildren
FROM dbo.Parent
WHERE Id = #ParentId
)
-
(
SELECT COUNT(Id)
FROM dbo.Child
WHERE ParentId = #ParentId
)
END;
Add the check constraint to the Child table:
ALTER TABLE dbo.Child
ADD CONSTRAINT chk_childCount CHECK (dbo.RestrictNumbrOfChildren(ParentId) >= 0);
And that's basically all you need, unless MaxNumberOfChildren is nullable.
In that case, you should add ISNULL() to the first query, with either 0 if null means no children are allowed, or the maximum value of int (2,147,483,647) if null means no restriction on the number of children - so it becomes SELECT ISNULL(MaxNumberOfChildren, 0)... or SELECT ISNULL(MaxNumberOfChildren, 2147483647)....
To test the script, let's insert some data to the Parent table:
INSERT INTO Parent (Id, MaxNumberOfChildren) VALUES
(1, 3), (2, 2), (3, 1);
And insert some valid data to the Child table:
INSERT INTO Child (Id, ParentId) VALUES
(1, 1), (2, 2);
So far, we have not exceeded the maximum number of records allowed. Now let's try to do that by insert some more data to the Child table:
INSERT INTO Child (Id, ParentId) VALUES
(3, 1), (4, 1), (5, 1);
Now, this insert statement will fail with the error message:
The INSERT statement conflicted with the CHECK constraint "chk_childCount". The conflict occurred in database "<your database name here>", table "dbo.Child", column 'ParentId'.
You can see a live demo on rextester.
Table:
CREATE TABLE appointment
(
id bigserial NOT NULL,
date_of_visit timestamp without time zone NOT NULL,
symptoms text[],
diseases text[],
lab_tests text[],
prescription_id bigint NOT NULL,
medicines jsonb,
CONSTRAINT appointment_pkey PRIMARY KEY (id),
CONSTRAINT appointment_prescription_id_fkey FOREIGN KEY (prescription_id)
REFERENCES prescription (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
Insert statement:
INSERT INTO appointment values(
1,
now(),
'{"abc","def","ghi"}',
'{"abc","def","ghi"}',
'{"abc","def","ghi"}',
1,
'[{"sku_id": 1, "company": "Magnafone"}, {"sku_id": 2, "company": "Magnafone"}]')
I am trying to query against a jsonb array type column in postgres. I had some solution in hand which is as below. Somehow it is not working The error is - Cannot extract elements from a scalar.
SELECT distinct(prescription_id)
FROM appointment
WHERE to_json(array(SELECT jsonb_array_elements(medicines) ->>'sku_id'))::jsonb ?|array['1']
LIMIT 2;
Update:
The query runs just fine. There was some unwanted value in the column for some other rows because of which it was not running.
There are rows in the table containing a scalar value in column medicines instead of array.
You should inspect and properly update the data. You can find these rows with this query:
select id, medicines
from appointment
where jsonb_typeof(medicines) <> 'array';
Alternatively, you can check the type of values in this column in the query:
select prescription_id
from (
select distinct on (prescription_id)
prescription_id,
case
when jsonb_typeof(medicines) = 'array' then jsonb_array_elements(medicines) ->>'sku_id'
else null
end as sku_id
from appointment
) alias
where sku_id = '1'
limit 2;
or simply exclude non-array values in where clause:
select prescription_id
from (
select distinct on (prescription_id)
prescription_id,
jsonb_array_elements(medicines) ->>'sku_id' as sku_id
from appointment
where jsonb_typeof(medicines) = 'array'
) alias
where sku_id = '1'
limit 2;
I have a Stored procedure, in which I have to insert 3 strings into 3 different Tables at a time, each string into each of the 3 tables.
In each table, a unique primary key (rowid) would be generated on insertion of the value.
Now, the Primary Key of first two tables is the Foreign key of the Third Table which as you all know, should not be null.
Here in my SP, insertion of value and generation of RowID (PrimaryKey) is done successfully.
Now I have to pass the two primary keys(Rowids) as values/Parameters(foreignkeys) into the third table, which is returning null.
Here is my SP:-
(1st Table)
INSERT INTO [kk_admin].[FA_Master](FA_Name,FA_CSession,FA_MSession) Values
(#FA_Name,#Session_Id,#Session_Id)
SELECT #**FA_ID=FA_ID** FROM [kk_admin].[FA_Master] where FA_Name=#FA_Name
(2nd Table)
INSERT INTO [kk_admin].[Dept_Master](Dept_Name,Dept_CSession,Dept_MSession) Values
(#Dept_Name,#Session_Id,#Session_Id)
SELECT #**Dept_id=Dept_id** from [kk_admin].[Dept_Master] where Dept_Name=#Dept_Name
(3rd Table)
INSERT INTO [kk_admin].[Category_Master] (**FA_Id**,**Dept_Id**,Category_Name,Category_CSession,Category_MSession) Values (#**FA_ID**,#**Dept_Id**,#Category_Name,#Session_Id,#Session_Id)
Hope everyone understood what I have explained.
Plz Help me,
Iam running out of time.
Plz help me.
Thank You in Advance,
Brightsy
You can use an OUTPUT clause (assuming you're using SQL Server 2005) to capture the primary key for the two rows you're inserting with the first two queries. You can capture the values into a temporary table. [I previously wrote that you could use a regular variable, but that's not supported.] Example code:
CREATE TABLE #FA_Master_ID ( ID int );
CREATE TABLE #Dept_Master_ID ( ID int );
INSERT kk_admin.FA_Master ( FA_Name, FA_CSession, FA_MSession )
OUTPUT INSERTED.ID INTO #FA_Master_ID
VALUES ( #FA_Name, #Session_Id, #Session_Id );
INSERT kk_admin.Dept_Master ( Dept_Name, Dept_CSession, Dept_MSession )
OUTPUT INSERTED.ID INTO #Dept_Master_ID
VALUES ( #Dept_Name, #Session_Id, #Session_Id );
INSERT kk_admin.Category_Master ( **FA_Id**, **Dept_Id**, Category_Name, Category_CSession, Category_MSession )
SELECT **FA_Id** = ( SELECT TOP 1 ID FROM #FA_Master_ID ),
**Dept_Id** = ( SELECT TOP 1 ID FROM #Dept_Master_ID ),
Category_Name = #Category_Name,
Category_CSession = #Session_Id,
Category_MSession = #Session_Id;