These are my tables:
Equipment
-------------
ID INT (PKey)
Name CHAR(10)
Type CHAR(10)
LocationID INT (FKey)
Description TEXT
Location
-------------
LocationID INT (PKey)
Name CHAR(10)
Code INT
The user is given a list of Location.Code to select when inputing new Equipment. (This is how the user identifies the Equipment.LocationID.)
However if I input the data for Location.Code as Equipment.LocationID it will break the system. Is there better way of doing this? For example can I come up with a way to select the Location.LocationID and use the in place of Equipment.LocationID?
NOTE I can't change what the user selects, that has to remain the same.
For example (pseudo code):
string userInput = "110"; // Location.Code
SELECT LocationID FROM Location WHERE Code = #userInput;
userInput = LocationID; // LocationID = 1;
INSERT INTO Equipment(LocationID) VALUES (#userInput);
Is this the best way or is there a more efficient way?
merge two queries into one as below
INSERT INTO Equipment(LocationID) SELECT LocationID FROM Location WHERE Code = '110';
Related
These are my classes
Public Class Student
{
Public int Id{get;set;}
public string Name {get;set;}
}
Public Class Department
{
Public int Id{get;set;}
public string Name {get;set;}
public IList <Student> StudentList{get;set;}
}
These are my tables
Student Table
Id |Name |Department
-----------------
1 |aa | 1
2 |bb | 1
3 |cc | 2
Department Table
ID | Name
----------
1 | xxx
2 | yyy
I need the all data of department with the corresponding list of student by using stored procedure
CREATE PROCEDURE test
(
)
AS
BEGIN
select Id as Id,
Name as Name,
----here I need all the corresponding data from student table as StudentList
from Department
Is it possible.. If so Please help me.
Apparently I what want is I want to write another procedure and call it for StudentList,Is it possible
Use join, i choose Left Join here so in case if department does not have corresponding students it will still be retrieved.
SELECT d.ID
,d.Name
,s.ID
,s. Name
FROM Deparment d
LEFT JOIN Student s ON s.Department = d.ID
So from your example the query will return the following result :
ID, Name, Student ID Student Name
1 xxx 1 aa
1 xxx 2 bb
2 yyy 3 cc
Assuming that your stored procedure will accept department id as parameter and retrieve all students under this department, just add a condition in your query
WHERE d.ID = #DeptID
As #Eugen said, just process the result in your application.
What you describe can be done, but it is not the normal process. You can use for xml to return a column where all of the student information is encoded. Note that while this results in all of the data you want being returned in a single row, you will have to create and populate all of your objects by hand. None of the ORM's like Entity Framework or nHibernate will populate both your department and students. In fact, you will probably end up parsing a string by hand in order to create your students.
The most common practice today would be to use Entity Framework and let it do all of the work for you.
Here's some code to show how you can do as you request. Again, note that this is not recommended, and that it's just one way of doing this:
create table #s (id int, name varchar(max), departmentId int);
insert into #s (id, name, departmentId)
select * from (values (1 , 'aa', 1) ,(2 , 'bb', 1) ,(3 , 'cc', 2)
) g(id, name, departmentId);
create table #d (departmentId int, name varchar(max));
insert into #d (departmentId, name) select * from (values
(1 , 'xxx') ,(2 , 'yyy')
)g(departmentId, name)
select *, (select id, name, departmentId
from #s s where s.departmentID = d.departmentId for xml path
)students
from #d d
drop table #d
drop table #s;
Students for deparment 1 =
<row><id>1</id><name>aa</name><departmentId>1</departmentId></row>
<row><id>2</id><name>bb</name><departmentId>1</departmentId></row>
In particular, you may find this a bit heavy, 2016 should be able to do something similar with JSON, but if you'd like that in the meantime, you'll have to customize the output yourself. It can be done, and wouldn't be too difficult.
I would like to join data from tables from two databases. One is filed with predefined values (itemId, itemName) and other is filled by user (itemId, itemName, userId). Atributes itemId and itemName are the same, from first table we select all data, from second we select data by userId and combine these two results.
Joined data should be distinguish because ids are autoincrement and could be the same(doubled). We would like to fill drop down list with this data for example with datasource and dictionary (int is itemId, string is itemName) we could only have valueFiled and valueText in dropDownList but ids of these two tables could be the same and lather we don`t know from wich table is item selected by id.
Is there any elegant way to joint this, maybe with temp tables that we always when user is logged in join these two tables in temp table etc...
Thank you for your answers
I think you're looking for a union. Use a literal value to identify the source.
select 'predefined' as source, itemid, itemname
from predefined_values_table
union all
select 'user', itemid, itemname
from user_supplied_values_table
where userid = ?;
If you can accommodate only two columns, you might be able to use something like this instead. But you'll have to undo the string concatenation to get the id number.
select 'p:' || itemid, itemname
from predefined_values_table
union all
select 'u:' || itemid, itemname
from user_supplied_values_table
where userid = ?;
Is there a way to query the database to retrieve information about the schema of a table? I'm interested in just getting a list of the Column names and whether they are primary keys; is this possible? I don't care about the type, just its name and whether it is a primary key.
Sample Table:
Table Organism
{
primary: int ID;
int Kingdom;
int Phylum;
int Class;
int Genus;
int Species;
nvarchar(50) Name;
}
Sample Usage:
List<Tuple<string, bool>> t = ReadTable("Organism");
t.ForEach(x => Console.WriteLine(x.Item2 ? x.Item2 + ": " + x.Item1 : x.Item1));
Sample Output:
True ID
Kingdom
Phylum
Class
Genus
Species
Name
I am using C#4.0 and SQL Server 2008 R2. I think this should be possible using the system tables but I don't know how to do it.
select col.*
from sys.columns col
join sys.tables tab on col.object_id = tab.object_id
where tab.name = #tabName
order by col.column_id
The system views contain a wealth of data and they are easy to use.
You can get field names with such hacky query
select * from Organism where 1=2
And Metadata can be retrieved with Information Schema Views , for example key usage:
SELECT * FROM databaseName.INFORMATION_SCHEMA.KEY_COLUMN_USAGE
Where TABLE_NAME='Organism'
I have a number of user ID's. I am inserting these into a group table which will contain a column for the user's ID and the group ID. This will allow me to use the query "SELECT user_id FROM groups WHERE group_id = '3';" to retrieve user ID's of all the members of group 3.
My problem is that I currently have a list of all users IDs, which I got from a form, using the statements :
int i = 0;
String[] names = { Request.Form["usernames"]Split(' ') }; //retrieving names from form
List<int> user_ids = new List<int>();
foreach(string name in names){
int user_id = db.QueryValue("SELECT user_id FROM users WHERE username = name");
user_ids.Add(user_id); //now I have a list of all user_ids
}
I now wish to insert this data into the groups table, where all of the user_id values in the list will have the same group_ID. How can I do this?
//create a group from users
"INSERT INTO group (group_id, user_id) VALUES(?,?);
What you are talking about is a many-many relationship. You already have a users table:
**users**
userid
username
You need an additional table in the middle. The group table will just have something like:
**group***
groupid
groupName
You would then have a table in the middle. This table would look something like this:
**user_groups**
userid
groupid
You could still use your code to insert a user,
int i = 0;
String[] names = { Request.Form["usernames"]Split(' ') }; //retrieving names from form
List<int> user_ids = new List<int>();
foreach(string name in names){
int user_id = db.QueryValue("SELECT user_id FROM users WHERE username = name");
user_ids.Add(user_id); //now I have a list of all user_ids
}
After this, you would insert a group:
insert into group(groupName) values("Sample Group")
Then you could retrieve the group id and use that to insert into user_groups
select groupid from group where groupname="Sample Group"
insert into user_groups(userid,groupid) values(...
Also, the table structure should include primary keys and foreign keys (much like #sixlettervariables' answer)
In order to make this cleaner, you'll probably want to refactor your database setup slightly such that a third table relates users to groups:
users (user_id pk, ...)
groups (group_id pk, ...)
membership (user_id fk, group_id fk) unique(user_id, group_id)
When you needed to make a new group you simply insert into the groups table, obtain the group_id, and use that to populate the membership table for each of the users in that group.
You can use the select as the input to the insert
INSERT INTO group (group_id, user_id)
SELECT 1, user_id FROM users WHERE username in ("name1", name2")
You can join the names array back together with some commas.
You will need to iterate the user_ids list and do a separate insert statement for each user id.
You can insert all of the User ID's from one table into another using a sub-select and union statement as follows:
INSERT INTO group_table_name([user_id]) SELECT [user_id] FROM table_name
UNION ALL
By the way, you might want to change that table name since "group" is a keyword in SQL Server. Just a tip.
Insert Into GroupTable (GroupId, UserID) Select GroupID, USerID from UserTable group by GroupID, UserID)
This would work :)
Assuming you already know 3, you can do this without pulling the user ids into a local list and then inserting them individually (put in quotes specifically because the OP has their query in a similar string):
"INSERT dbo.group(group_id, user_id)
SELECT 3, user_id
FROM dbo.users
WHERE username = name;"
If you don't already know the group id, then please explain how you determined the group id should be 3.
EDIT based on further info.
CREATE TABLE dbo.Groups
(
GroupID INT IDENTITY(1,1) PRIMARY KEY,
GroupName NVARCHAR(255) NOT NULL UNIQUE
);
CREATE TABLE dbo.GroupUsers
(
GroupID INT NOT NULL FOREIGN KEY
REFERENCES dbo.Groups(GroupID),
UserID INT NOT NULL FOREIGN KEY
REFERENCES dbo.Users(UserID),
PRIMARY KEY(GroupID, UserID)
);
Now when you want to create a new group and add users to it:
DECLARE #GroupID INT;
INSERT dbo.Groups(GroupName) SELECT N'whatever (unique)';
SELECT #GroupID = SCOPE_IDENTITY();
Now you can loop through each user id:
INSERT dbo.GroupUsers(GroupID, UserID) SELECT #GroupID, <userid>;
Here is the my problem: I have a SQL Server database called emp. It has an employee table (with userid int column). I need to retrieve the last record of the userid in employee table with increment userid value + 1. At the moment I did it on the my GUI. So how do I write a sql query for it?
To return the the record with the highest userid, you can do:
SELECT TOP 1 userid
FROM employee
ORDER BY userid DESC
or...
SELECT MAX(userid)
FROM employee
If your plan is to then increment the userid manually and insert a new record with that new ID, I'd recommend against doing that - what if 2 processes try to do it at the same time? Instead, use an IDENTITY column as userid and let the incrementing be handled for you automatically
You shouldn't be manually incrementing the userid column, use an IDENTITY column instead. That will automatically add 1 for you for every new row.
CREATE TABLE Employees (
UserId INT IDENTITY PRIMARY KEY NOT NULL,
UserName NVARCHAR(255) NOT NULL,
// etc add other columns here
)
If you really really have to select the highest userid it is a very simple query:
SELECT MAX(UserId) + 1
FROM Employees
[Edit]
Based on your comments, you should use the SELECT MAX(UserId) + 1 FROM Employees query. But be aware that this does not guarantee the number will be the ID. Normally you would not show an Id value until after the record has been saved to the database.
This will give you last inserted record, If you don't have Identity column.
EXECUTE ('DECLARE GETLAST CURSOR DYNAMIC FOR SELECT * FROM [User]')
OPEN GETLAST
FETCH LAST FROM GETLAST
CLOSE GETLAST
DEALLOCATE GETLAST
If you have set identity than you can use following.
SELECT top(1) ID from [YourTable] order by ID desc
To have the new userid before saving, create a NextId table.
Before inserting the user, get the new value from NextId:
UserId = SELECT Coalesce(NextId, 0) + 1 from NextId
Then update the NextID table:
UPDATE NEXTID SET NextId = IserID
And then use that value in your user creation code
You can get gaps, there are more complicated methods to avoid them; but I think this will do