Let's say after I had login I will be prompt to enter the Name and address how do I insert data with at least 2 table linking to each other using Store procedures?
Try something like this:
CREATE PROC dbo.user_Add(
#username VARCHAR(50),
#password NVARCHAR(50)
)
AS
BEGIN
-- username should be unique
IF NOT EXISTS(SELECT TOP 1 1 FROM Login WHERE username = #username) BEGIN
INSERT INTO Login (username, password)
VALUES (#username, #password)
RETURN ##IDENTITY
END
ELSE BEGIN
-- already taken username should be handled somehow
RETURN 0
END
END
CREATE PROC dbo.user_StudentAdd(
#loginID INT,
#name NVARCHAR(50),
#addr NVARCHAR(100)
)
AS
BEGIN
-- add new record for new student
-- probably before you should check if student is not already exist
INSERT INTO Student (LoginID, [Student Name], [Student address])
VALUES (#loginID, #name, #addr)
-- returns new StudentID, you can also use `RETURN` to return StudentId (if you need it)
SELECT ##IDENTITY
END
As your homework you can write a third stored procedure which calls two above
and use result from first one in second one. Hint -- use EXEC to assign value returned by
stored procedure (here are details: http://msdn.microsoft.com/en-us/library/ms174998.aspx).
I didn't test it, so it can fails due to misspelling.
Also I've never used columns with space inside so I am not sure how to handle them.
I assume that:
User (record in login table) already exists and value of login.loginID is accessible (user has already logged-in).
It was checked that logged-in user needs to fulfill his students data.
One more thing -- I would not use column names with space (or non-Latin characters).
Related
I'm preventing the user from adding the same surname in the list in the code array below. But my goal is to check all the lines using the 'trigger'. As a result: what do I need to do to check all the columns?
In summary: Check all columns. If the same value is entered, prevent it from being added.
ALTER TRIGGER trigger_example
ON dbo.information
INSTEAD OF INSERT
AS
DECLARE #surname varchar(30)
select #surname = Person_Job FROM inserted
IF(#surname = 'Enderson')
BEGIN
PRINT 'The person with this record already exists in the list.'
END
ELSE
BEGIN
INSERT INTO personel.dbo.information(Person_id,Person_FirstName,Person_LastName,Person_Salary,Person_Job)
SELECT Person_id,Person_FirstName,Person_LastName,Person_Salary,Person_Job FROM inserted
END
GO
enter image description here
mark the column as unique
add up a constraint:
unique
I have a database Users that has four fields: Name, Client, ID, Time. Client is an integer (0-99). How to write a trigger that will find latest user from Users (latest according to Time) during Insert and if the Client of this user equals Client of inserted user then I'd like to Rollback
I tried like this:
CREATE TRIGGER DoubledData ON Users
FOR INSERT
AS
DECLARE #client DECIMAL(2)
DECLARE #client_old DECIMAL(2)
DECLARE #name Varchar(50)
SELECT #name = Name from inserted
SELECT #client = Client from inserted
//This doesn't work, "Syntax error near Select":
SELECT #client_old = Select top(1) Client from Users where Name like #name order by Time desc;
IF #client = #client_old
BEGIN
ROLLBACK
END
The problem is that I can assign same values to Client for one user but they can't be one after another (eg for client this order is correct 1-2-3-1-3 -> order is important, but this isn't correct: 1-2-3-3 -> after 2nd occurrence of '3' in a row it needs to be rollbacked)
I'm using MS SQL
[EDIT]
I have found that I can execute it without Select top(1) like:
SELECT #client_old = Client from Users where Name like #name order by Time desc;
But the trigger doesn't execute afer insert
First, you clearly don't understand triggers in SQL Server and the inserted pseudo-tables. These can have more than one row, so your code will fail when multiple rows are inserted. Sadly, there is no compile check for this situation. And code can unexpectedly fail (even in production, alas).
Second, the right way to do this is probably with a unique constraint. That would be:
alter table users
add constraint unq_users_name_client unique (name, client);
This would ensure no duplication, so it is a stronger condition than your trigger.
The goal is to get the amount of passwords the user has, compare it with the company's rules. If it exceeds the number they allow, we insert the new one (with the date) and delete the last one (or delete the last one then insert the new one. I honestly have figured out which way I want to go yet).
I have two stored procedures: Delete_Oldest_Password_And_Date and Number_Of_Passwords
Delete_Oldest_Password_And_Date calls Number_Of_Passwords because I need that amount.
I'm pretty sure the beginning of my stored procedure is good. It's the second half, starting with #Temp_Password_Table.
CREATE Procedure Delete_Oldest_Password_And_Date
#ua_pk uniqueidentifier
AS
DECLARE #Temp_Table table
(
numberOfPasswords INT
)
INSERT INTO #Temp_Table
EXEC Number_Of_Passwords #ua_pk
SELECT *
FROM
#Temp_Table
DECLARE #Temp_Password_Table table
(
password varchar(max)
)
SELECT *
FROM User_Passwords
WHERE User_Passwords.ua_fk = #ua_pk
AND up_Password LIKE '%Password%'
GO
GRANT EXEC ON Delete_Oldest_Password_And_Date TO WEB
GO
I'm not worried about the delete just yet. I'm more worried about getting the correct information first.
Keep in mind User_Passwords is dynamic per person. The plan (I haven't gotten to this part yet) is to have the newest go into a column named "up_Password1", then the second newest into column "up_Password2", etc.
Here's a proc that will check the number of passwords a user has, and will delete the oldest password(s) until there are Max#ofPasswords-1, thus setting up for a new password to be inserted that still follows the policy for number of historical passwords. The proc assumes the following table:
CREATE TABLE dbo.User_Passwords(
ua_fk UNIQUEIDENTIFIER,
password_hash NVARCHAR(100),
start_date DATETIME,
end_date DATETIME)
Password_hash can be whatever you decide to store the password column as (just please don't store actual passwords in plain text here).
CREATE Procedure Delete_Oldest_Password_And_Date
#ua_pk uniqueidentifier
AS
DECLARE #numberOfPasswords INT,
#MaxPasswordNum INT = 10
SELECT #numberOfPasswords = COUNT(*)
FROM User_Passwords
WHERE ua_fk = #ua_pk
IF #numberOfPasswords >= #MaxPasswordNum
BEGIN
WITH T
AS (SELECT TOP (#numberOfPasswords - (#MaxPasswordNum-1)) *
FROM User_Passwords
WHERE ua_fk = #ua_pk
ORDER BY end_date ASC)
DELETE FROM T;
END
GO
Ive got a question which I am completely stumped on. It reads as follows:
Write a import stored procedure that take information from a table (source) and write it into another table (target).
Im guessing it would look something like the following:
create procedure add_data(#name, #surname)
AS
BEGIN
SELECT name, surname
FROM cardholder
INSERT INTO new_table
values (name, surname)
Is my logic correct or am I completely missing it?
You are almost there. Since you are directly copying from one table to another, you can use the INSERT INTO ... SELECT ... idiom, like so:
create procedure add_data
#name varchar(100)
#surname varchar(100)
AS
BEGIN
INSERT INTO new_table(name,surname)
SELECT name, surname
FROM cardholder
END
Note the 2 changes I made:
How you declare the parameters for the SP
The values clause should consist of the actual values being inserted. Since you are inserting data retrieved from a table rather than fixed values, you use the select query instead.
Try the following code.
create procedure add_data(#name VARCHAR(10), #surname VARCHAR(10))
AS
BEGIN
INSERT INTO new_table(name, surname)
SELECT name, surname
FROM cardholder
END
It would insert data from one table to another so in output what ever the parameters pass it will inserted into new table just plain and simple.
It is not correct. try dis
create procedure add_data
(
#name varchar(100),
#surname varchar(100)
)
AS
BEGIN
INSERT INTO target
SELECT name, surname
FROM cardholder
end
I have a stored procedure that inserts a user into a table but I want an output value equals to the new inserted UserID in the table but I don't know how to do it can you guys help me?
I have this
ALTER PROCEDURE dbo.st_Insert_User
(
#Nombre varchar(200),
#Usuario varchar(100),
#Password varchar(100),
#Administrador bit,
#Resultado int output
)
AS
INSERT INTO tbl_Users(Nombre, Usuario, Password, Administrador)
VALUES(#Nombre, #Usuario, #Password, #Administrador)
SELECT #resultado = UserID
I also tried
SELECT #resultado = UserID FROM tbl_Users WHERE Usuario = #Usuario
SELECT SCOPE_IDENTITY()
will give you the identity of the row
For SQL Server, you want to use the OUTPUT clause. See information and examples in Books Online here. It does cover your case-- as it mentions "The OUTPUT clause may be useful to retrieve the value of identity or computed columns after an INSERT or UPDATE operation."
(If this is for real world purposes, you do of course have security concerns in storing passwords that you should address.)
Add at the end
select ##Identity