add new column if the previous one is not null - c#

I need to create sqlite statement that checks if a specific column value is not null then add a new column and insert the new value.
What I already have is this :
CREATE TABLE "StuPayment" (
"PayNumber" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
"StudentName" ntext,
"CourseName" ntext,
"PayDate" datetime,
"CheckNumber" NUMERIC,
"Amount" NUMERIC
)
What I want to create is a new payment columns (PayDate1,CheckNumber1,Amount1) when a student pays a course cost on two payments or maybe three sometimes.
Thanks for your time reading this.

No. Don't do it. Just record the payments in multiple rows. You already have a datetime column, so each payment is recorded separately.
There are multiple advantages to new rows:
You can easily search for things like amount > 1000 and not have to worry about extra columns.
You can use an index to search on the payment columns, such as getting all payments on a particular date.
PayNumber uniquely identifies each payment.
You don't have to reserve space for empty values in all the rows.
Adding new payment methods (say credit cards, debit cards, direct debit, or other mechanisms) is simpler, because you don't have to multiply the columns for each potential payment.
You can more easily support payment plans, such as one payment per week.
Your concern about 10,000 rows/year is not relevant in today's world. Databases and computers are powerful.
If you want to see all the payments that a student has made, you can use:
select studentname, coursename, count(*) as numpayments, sum(amount)
from stupayment
group by studentname, coursename;

I would recommend to have a view created and do whatever manipulation you want as I see theres unclear logical requirement. Go for view Creation
Create view as (Select * from table) ;
Alter view add column c1 ;

Related

C# SQL Insert statement - if first column has text insert into the next

I have built an RFID Race Timing system and all is functioning well but now I need to either insert or update the tblMovement entry.
When inserting I must use tagID, movementDate, checkDate. movementDate is the actual tag read time. checkDate is for my anti collision functionality. When inserting it must place the movementDate into #Lap1.
When updating I must locate the tagID and check if #Lap1, #Lap2, #Lap3, #Lap4 or #Lap5 have data. If #Lap3 has data then I must insert into #Lap4 etc.
My SQL search query which locates the tagID is functioning fine and it either Updates or Inserts based on the results. My biggest challenge is scanning each column to see which has data. I have source code but its too much for this window.....
Rather than having 5 lap times, it would be good to break this out into a normalized structure. That would mean having a tblMovementLaps table, with the following structure.
CREATE TABLE dbo.tblMovementLaps(
[Id] INT NOT NULL IDENTITY(1,1),
[TagId] INT NOT NULL,
[MovementDate] DATETIME NOT NULL,
[CheckDate] DATETIME NOT NULL
)
You would insert a new record into tblMovement at the start of each race, and a new record into tblMovementLap every time you were recording a new lap. Then you would join between the two to review a race, with:
SELECT *
FROM [tblMovement] TM
JOIN [tblMovementLaps] TML
ON TM.[TagId] = TML.[Id]
ORDER BY TML.[Id] ASC
A big benefit of doing things this way - it lets you record races of infinite lap counts without breaking your structure or expanding your movement table into more and more columns. Also it lets you keep space in the movement table available for information that is truly unique to each race (the basis of normalization), like the racer ID, race date, etc.
All that said, if you REALLY wanted to continue to support your current structure, you could add a [CurrentLap] field to TblMovement. Always insert your lap time to that field. Set up an UPDATE trigger on your table to move that value into one of the #lap fields based on which are populated

How to pull a SQL Table entry based on highest IDENTITY entry and update two columns

I'm not well versed in SQL operations, and would like some help with a task I need to complete in code. I have written a cloud based app that accesses a SQL table containing test results - device ID's, serial numbers, test results etc.
There is a use-case where someone in the field would activate a menu where an update to this table occurs. When the device test result table is updated, I want to store the OLD information in a device test history table. This way, we can go back and see what was changed over time.
So I need to pull all the columns from the TestedDevice table, insert them into TestedDeviceHistory table, and include some additional information; the current date and the operator's id. (these are two new columns found only in TestedDeviceHistory)
At first, I'm using a SELECT INTO command, as follows:
SELECT *
INTO dbo.TestedDevicesHistory
FROM dbo.TestedDevices
WHERE CertificateID = #cert
Then I'm attempting this (obviously broken) SQL command:
UPDATE dbo.TestedDeviceHistory
SET Caller = #caller,
RecordDate = #date
WHERE DeviceHistoryID = MAX(DeviceHistoryID)
Notes:
DeviceHistoryID is an IDENTITY integer column, so it's unique for each entry made in the history table.
CertificateID is unique in the TestedDevices table. It is expected NOT to be unique in the history table.
The code is written in C# 4.5
Maybe this is a case for a stored procedure, which I have never attempted to create or use. Or, perhaps the use of a cursor? Don't know! This is why I'm humbly asking for the more experienced with SQL to help :)
Not clear on if you only want to assign the Caller and RecordDate to the most recent record, or if it could be assigned to all the history records.
For all records, I believe you can do something like
SELECT *, #caller AS Caller, #date AS RecordDate INTO dbo.TestedDevicesHistory
FROM dbo.TestedDevices WHERE CertificateID=#cert

Holding different datatypes dynamically in database

Lets say I have a table Person and I need that a user can add different attributes to him/herself.
User should be able to add a date, string, number, boolean, multiple values.
Lets say he wants to add:
Date of birth
Name
Heigth
Children names
How would I hold this in database?
I have 2 ideas:
I can hold all the values as string or varchar and always parse the value back to original format when used. Multiple values holding like text1#text2#text3 or similar.
Having a table, where there are columns for each : date, string, number and only the one that is needed will be populated and other will stay nulls.
Any suggestions?
Good database design should always be N:1 (many to one) or 1:1 (one to one), never 1:N (one to many) or N:N (many to many), meaning that if you have multiple related fields of a user, you should make a new table that refers to the user.
Since a user can only have one birth date though, you should keep that as a column to the Users table.
For example, in this case you want children names as the "multiple", assigned to one user.
A simple table for that could look like this:
ID int primary key
UserID int references User(ID)
Name varchar
That way, you can make multiple children names for one user, while still being able to keep constraints in the database (which helps ensure code correctness if you're interfacing with it through an application!)
Some people will suggest having a table for each of the values, just to avoid nulls. For example, to store their birthdate, you make a table similar to the Children names table above, since you won't have to make a column in the Users table that might be null.
Personally I think using nulls are fine, as they allow you to see if there is a relevant result set without joining (or worse, left joining) an entire table of potentially irrelevant information.
Use your second approach. In your table 'Person', have a row for each record that has multiple columns each which holds a single value for you desired fields.
So..
tbPerson
ID | Date Of Birth | Name | Height | Childrens names | etc...
To Create a table...
CREATE TABLE tbPerson([ID] INT IDENTITY(1,1), [Date Of Birth] DATE, [Name] VARCHAR(50), Height INT, [Childrens names] VARCHAR(250))
This is the best and easiest way and enables editing 1 field of a persons records simple. In your first approach you will have endless nightmares storing everything a 1 long string.

limiting the records inserted in a sql table

I have the requirement to build a asp.net sign up form which will allow students to register a training. So far I built a database in sql server and 3 tables: student, training & studenttraining
My question is, how can I limit the form from displaying the dates available once a particular training gets full, or meabe how can I prevent by checking the tables that the user can register?
Select count(*) as SeatsFilled, t.TrainingKey, t.TrainingDate
From Training t
Inner Join StudentTraining st on t.TrainingKey = st.TrainingKey
Group By t.TrainingKey, t.TrainingDate
Having count(*) < t.TotalSeats
TotalSeats is a column in the Training table that specifies how many seats the training provides. I assumed StudentTraining is a many-to-many bridge table between Students and Training.
You'll need to establish what "full" is first. Then, you can do a simple
SELECT COUNT(id) FROM table to determine if the full amount is already reached.
I guess you could have a MaxTraining column in the training table and when you get the data for your form, you can count the training entries in studenttraining, and if it equals MaxTraining, then don't bring that training entry, cause it means it's already full.

Best way of acquiring information from several database tables

I have a medical database that keeps different types of data on patients: examinations, lab results, x-rays... each type of record exists in a separate table. I need to present this data on one table to show the patient's history with a particular clinic.
My question: what is the best way to do it? Should I do a SELECT from each table where the patient ID matches, order them by date, and then keep them in some artificial list-like structure (ordered by date)? Or is there a better way of doing this?
I'm using WPF and SQL Server 2008 for this app.
As others have said, JOIN is the way you'd normally do this. However, if there are multiple rows in one table for a patient then there's a chance you'll get data in some columns repeated across multiple rows, which often you don't want. In that case it's sometimes easier to use UNION or UNION ALL.
Let's say you have two tables, examinations and xrays, each with a PatientID, a Date and some extra details. You could combine them like this:
SELECT PatientID, ExamDate [Date], ExamResults [Details]
FROM examinations
WHERE PatientID = #patient
UNION ALL
SELECT PatientID, XrayDate [Date], XrayComments [Details]
FROM xrays
WHERE PatientID = #patient
Now you have one big result set with PatientID, Date and Details columns. I've found this handy for "merging" multiple tables with similar, but not identical, data.
If this is something you're going to be doing often, I'd be tempted to create a denormalized view on all of patient data (join the appropriate tables) and index the appropriate column(s) in the view. Then use the appropriate method (stored procedure, etc) to retrieve the data for a passed-in patientID.
Use a JOIN to get data from several tables.
You can use a join (can't remember which type exactly) to get all the records from each table for a specific patient. The way this works depends on your database design.
I'd do it with separate SELECT statements, since a simple JOIN probably won't do due to the fact that some tables might have more than 1 row for the patient.
So I would retrieve multiple result-sets in a simple DataSet, add a DalaRelation, cache the object and query it down the line (by date, by exam type, subsets, ...)
The main point is that you have all the data handy, even cached if needed, in a structure which is easily queried and filtered.

Categories