In stored procedure MS SQL My query is:
SELECT *
FROM ContentReportRequests a,UserPreferences d
WHERE a.UserID = d.UserID and a.ID =#ID
I want to give the result table some name.
How can I do this ?
I want to pull it to ADO.Net DataSet.tables["NAME"]
I can imagine a few things you might be meaning.
If you want to persist this result set, for consumption in multiple later queries, you might be looking for SELECT INTO:
SELECT * into NewTableName
FROM ContentReportRequests a,UserPreferences d
WHERE a.UserID = d.UserID and a.ID =#ID
Where NewTableName is a new name, and a new (permanent) table will be created. If you want that table to go away when you're finished, prefix the name with a #, to make it a temp table.
Alternatively, you might just be wanting to absorb it into a single larger query, in which case you'd be looking at making it a subselect:
SELECT *
FROM (SELECT *
FROM ContentReportRequests a,UserPreferences d
WHERE a.UserID = d.UserID and a.ID =#ID
) NewTableName
WHERE NewTableName.ColumnValue = 'abc'
or a CTE:
WITH NewTableName AS (
SELECT *
FROM ContentReportRequests a,UserPreferences d
WHERE a.UserID = d.UserID and a.ID =#ID
)
SELECT * from NewTableName
Finally, you might be talking about pulling the result set into e.g. an ADO.Net DataTable, and you want the name to be set automatically. I'm not sure that that is feasible.
You can use a variable of type table. Read more here: Table Variables In T-SQL
in stored procedure:
select CH.PrimaryKey, CH.Name,
NULL "CustomerHeader"
from CustomerHeader "CH";
--
select CD.PrimaryKey, CD.ShipTo,
NULL "CustomerDetail"
from CustomerDetail "CD";
--
select *, NULL "Orders"
from OrderTable;
in Vb.Net code:
Dim ds As DataSet = Nothing
ds = SqlExecute();
Dim dtCustHeader As DataTable = Nothing
Dim dtCustDetail As DataTable = Nothing
Dim dtOrders As DataTable = Nothing
For Each dt As DataTable In ds.tables
Select Case True
Case dt.Columns.Contains("CustomerHeader")
dtCustHeader = dt
Case dt.Columns.Contains("CustomerDetail")
dtCustDetail = dt
Case dt.Columns.Contains("Orders")
dtOrders = dt
End Select
Next
Kinda SILLY (OR STUPID) that you cannot name tables in a result set.
But this gets you there without a HUGE byte count repeating the table name within each row.
There is still overhead passing the NULL value back for each row. Perhaps passing a BIT value would be smaller yet...
And an alternative is to always use column(0):
in SQL:
select NULL "CustomerDetail", CustName,Addr1,Addr2... from CustomerDetail;
in vb.net:
Dim ds As DataSet = Nothing
ds = SqlExecute();
Dim dtCustHeader As DataTable = Nothing
Dim dtCustDetail As DataTable = Nothing
Dim dtOrders As DataTable = Nothing
For Each dt As DataTable In ds.Tables
Dim tblName As String = dt.Columns(0).ColumnName
Select Case tblName.ToUpper
Case "CUSTOMERDETAIL" : dtCustHeader = dt
Case "CUSTOMERDETAIL" : dtCustDetail = dt
Case "ORDERS" : dtOrders = dt
End Select
Next
These methods get your table-names even if the query returns zero rows.
but the best for last... a way to actually name the tables in the dataset automatically, every time FROM SQL STORED PROCEDURE (with help from your code):
Dim ds As DataSet = Nothing
ds = SqlExecute();
For Each dt As DataTable In ds.Tables
dt.TableName = dt.Columns(0).ColumnName
Next
After this, you may access your tables with the name YOU control within the stored procedure... as it should have been from day-one!
EDIT: selective implementation:
Name the first column in the pattern "TN:Customer".
Your legacy stored procedures work normally, only impacting the stored procedures you wish to modify.
For Each dt As DataTable In mo_LastDataset.Tables
Dim tblName() As String = dt.Columns(0).ColumnName.Split(":")
If tblName.Length >= 2 AndAlso tblName(0).ToUpper = "TN" Then
dt.TableName = tblName(1)
End If
Next
... david ...
SELECT * AS MyTableName
FROM ContentReportRequests a, UserPreferences d
WHERE a.UserID = d.UserID and a.ID =#ID
Related
In VB.NET am trying to return all databases that have a specific table. The code I have been using polls just the databases and that works fine. When I add the CASE statement below to get just the ones with the table I need then it returns nothing.
strQuery = "SELECT [name] FROM sys.databases where create_date > '2016-07-01' and [name] not like '_Config_Options' order by create_date desc"
sqlCon = New SqlConnection(strConn)
Using (sqlCon)
Dim sqlComm As SqlCommand = New SqlCommand(strQuery, sqlCon)
sqlCon.Open()
Dim sqlReader As SqlDataReader = sqlComm.ExecuteReader
If sqlReader.HasRows Then
While (sqlReader.Read())
cmbDatabase.Items.Add(sqlReader.GetString(0))
End While
End If
sqlReader.Close()
End Using
The above code returns the full list of databases.
When I change the strQuery to
strQuery = "SELECT [name] FROM sys.databases WHERE CASE WHEN state_desc = ''ONLINE'' THEN OBJECT_ID(QUOTENAME([name]) + ''.[dbo].[MyTable]'', ''U'') END IS NOT NULL order by create_date desc"
I get nothing back. After executing Dim sqlReader As SqlDataReader = sqlComm.ExecuteReader, the code jumps to the End Using. I don't see an error code.
Joel Coehoom gets the credit for answering. I removed the double single quotes and it works.
strQuery = "SELECT [name] FROM sys.databases WHERE CASE WHEN state_desc = 'ONLINE' THEN OBJECT_ID(QUOTENAME([name]) + '.[dbo].[MyTable]', 'U') END IS NOT NULL order by create_date desc"
I have relational database. Each students has different history(one to many). The data is correct but the problem here is that student information become repetitive when loading in datagridview.I use DISTINCT function but it does not work. Can someone help me to figure out what's wrong with my code.
vb.net code when load
Using cmd As New SqlClient.SqlCommand("dbo.uspSELECTALL", cn)
da.SelectCommand = cmd
dt.Clear()
da.Fill(dt)
dgv1.RowTemplate.Height = 50
dgv1.DataSource = dt
For i As Integer = 0 To dgv1.Columns.Count - 1
If TypeOf dgv1.Columns(i) Is DataGridViewImageColumn Then
DirectCast(dgv1.Columns(i), DataGridViewImageColumn).ImageLayout = DataGridViewImageCellLayout.Stretch
End If
Next
End Using
stored procedure code
ALTER PROCEDURE [dbo].[uspSELECTALL]
AS
BEGIN
SET NOCOUNT ON;
SELECT DISTINCT SI.StudentID,SI.Surname,SI.FirstName,SI.MiddleName, SI.StudAddress ,
SI.BirthDay,SI.Gender, SI.Nationality, SI.BirthPlace,
SI.TelNum,SI.SchoolWhereGraduated ,
SI.DatesWhenGraduated, SI.SchoolLastAttended,
SI.Note,SI.StudImage,
PI.Father_FirstName,PI.Father_LastName,
PI.Father_MI,PI.Father_Occupation,
PI.Father_TelNUm, PI.Mother_FirstName, PI.Mother_LastName,
PI.Mother_MI,PI.Mother_Occupation,PI.Mother_TelNum,
PI.Contact_FirstName,PI.Contact_LastName,PI.Contact_MI,
PI.Contact_Mobile,PI.Contact_TelNum,PI.Contact_Address,
SH.SchoolYear,SH.Levels,SH.Section,SH.DateEnrolled
FROM StudentInformation SI
JOIN StudentHistory SH
ON SI.StudentID = SH.StudentID
JOIN ParentInformation PI
ON PI.ParentID = SI.ParentID
END
If you want show in the DataGridView only distincts id's of students,
then you need use another query.
Your current query always return multiply rows per student if student have more then one history.
One approach will be removing all columns of table StudentHistory from SELECT statement and keep DISTINCTkeyword in the query.
SELECT DISTINCT SI.StudentID,SI.Surname,SI.FirstName,SI.MiddleName, SI.StudAddress ,
SI.BirthDay,SI.Gender, SI.Nationality, SI.BirthPlace,
SI.TelNum,SI.SchoolWhereGraduated ,
SI.DatesWhenGraduated, SI.SchoolLastAttended,
SI.Note,SI.StudImage,
PI.Father_FirstName,PI.Father_LastName,
PI.Father_MI,PI.Father_Occupation,
PI.Father_TelNUm, PI.Mother_FirstName, PI.Mother_LastName,
PI.Mother_MI,PI.Mother_Occupation,PI.Mother_TelNum,
PI.Contact_FirstName,PI.Contact_LastName,PI.Contact_MI,
PI.Contact_Mobile,PI.Contact_TelNum,PI.Contact_Address
FROM StudentInformation SI
JOIN StudentHistory SH
ON SI.StudentID = SH.StudentID
JOIN ParentInformation PI
ON PI.ParentID = SI.ParentID
Another way will be filter DataTable which was filled by your query.
Using cmd As New SqlClient.SqlCommand("dbo.uspSELECTALL", cn)
da.SelectCommand = cmd
dt.Clear()
da.Fill(dt)
dgv1.RowTemplate.Height = 50
'Filtering for distinct rows
Dim view As New DataView(GetData())
Dim distinctColumnNames As String() =
{
"StudentID", "Surname", "FirstName", "MiddleName",
"StudAddress" ' and so on
}
Dim distinctValues As DataTable = view.ToTable(True, distinctColumnNames)
dgv1.DataSource = distinctValues
'Your other code
End Using
view.ToTable(True, distinctColumnNames) if first parameter is True then only distinct rows, based on columnnames will be included
Lets say i have two tables with almost the same structure
TableFrom
ID bigint
Username nvarchar
Password nvarchar
Name nvarchar
TableTo
ID bigint
Username nvarchar
Password nvarchar
Now i want to generate an Insert into SQL query ( using parameters ) but only for those fields who are the same in both tables. ( id, username, password )
I thought about reading those two table structure queries into dataTable and after that loop with LINQ to get array of fields which are the same in bot tables ?
Dim dtFrom as new datatable
dim dtTo as NEW dataTable
dtTo = _LoadAvaliableToFields()
dtFrom = _loadAvailableFromFields()
How would that LINQ go ?
After that i need to add the Insert query to database using parameters. Is there any simpler way to do this ?
Using query syntax the "select" query would be very similar to a SQL query:
Dim query =
From idFrom In TableFrom _
Join idTo In TableTo _
On New With {Key .ID = idFrom.ID, Key .U = idFrom.Username, Key .P = idFrom.Password} _
Equals New With {Key .ID = idTo.ID, Key .U = idTo.Username, Key .P = idTo.Password} _
Select idFrom
To do an insert you'd need to add objects to the appropriate collections in the context, then call SaveChanges.
I would note that a direct SQL query would be more efficient:
INSERT INTO {destination}
SELECT f.ID,f.Username,f.Password
FROM TableFrom f
INNER JOIN TableTo t
ON f.ID = t.ID AND f.Username = t.Username AND f.Password = t.Password
if i click the search button, i keep on receiving an error at the value of IDNo, incorrect syntax near '11111' can someone help me?
With acc
IDNo = .IDNo
StartDate = DateTime.Parse(.StartDate).ToString("M/d/yyyy")
EndDate = DateTime.Parse(.EndDate).ToString("M/d/yyyy")
ProjectName = .ProjectName
ReferenceNo = .ReferenceNo
TaskCode = .TaskCode
FileName = .Filename
End With
dgAccomplishment.DataSource = Nothing
dgAccomplishmentPT.DataSource = Nothing
da = New SqlDataAdapter("dbo.process_time #User='" & IDNo & "' ,#From='" & StartDate & "',#To='" & EndDate & " 11:59:59 PM'", DB.GetConnection)
dt = New DataTable
da.Fill(dt)
dgAccomplishment.DataSource = dt
dgAccomplishment.Columns("ID").Visible = False
dgAccomplishment.Columns("TimeSave").Visible = False
da.Dispose()
dt.Dispose()
this is my stored procedure
SELECT a.ID, RTRIM(a.Last_User) [ID No.],
RTRIM(Users.FIRSTNAME + ' ' + Users.INITIAL + '. ' + Users.LASTNAME) [Name],
RTRIM(a.ProjectName) [Project Name],
a.ProjectNo, a.ProjectCode,
RTRIM(a.Filename) [Filename],
RTRIM(a.Filesize) [Filesize],
RTRIM(a.filesizeunit) [FileSizeUnit],
a.TimeSave [TimeSave]
from DBase.dbo.Acc a
INNER JOIN dbo.Users ON a.Last_User = Users.IDNo
WHERE a.Last_User in (#user)
and CONVERT(VARCHAR(10),timesave,101) BETWEEN #From AND #To
ORDER BY RTRIM(a.SubGroup), RTRIM(a.Last_User)
but when i try to run the procedure in a query it works well.
Because you are using string concatenation, you have the age old single quote problem: If IDNo value contains a single quote, then your query will fail.
What's worse, your code is susceptible to sql injection attacks.
You have to escape ALL parameters for single quotes, replacing them by 2 single quotes.
Best solution here: use parametrized sql
I am trying to access the result from 2 select statement in vb.net, but I can only access the data from the 1st select statement.
CREATE PROCEDURE [dbo].[pr_testproc]
AS
BEGIN
SET NOCOUNT ON;
SELECT
comp_name, p_center, branch_id
FROM
tbl_company B
INNER JOIN
tbl_b_office X ON X.batch_id = B.tran_id
WHERE
X.office_stat = 1
ORDER BY
comp_name ASC;
SELECT
xcomp_name, xp_center, xbranch_id
FROM
tbl_company B
INNER JOIN
tbl_b_office X ON X.batch_id = B.tran_id
WHERE
X.office_stat = 0
AND MONTH(X.post_dt) = MONTH(GETDATE())
AND YEAR(X.post_dt) = YEAR(GETDATE())
ORDER BY
comp_name ASC;
END
Example if I try to get the result for data in 2nd table
getData(intRow).xcomp_name
This gets the error:
Object reference not set to an instance of an object.
But this would get the data
getData(intRow).comp_name
will get the value of the field.
Collect the output data to a Dataset so that, you can take the result of first select query from the DataTable in the 0th index of the dataset.
this May help you:
Dim myDataSet=GetDataSetFromSP("yourSPName")
Dim FirstResult As DataTable=myDataSet.Tables(0)
Dim SecontResult As DataTable=myDataSet.Tables(1)
Here you have to write the function that will execute the SP and return DataSet.
You could also combine the 2 queries into one.
CREATE PROCEDURE [dbo].[pr_testproc]
AS
BEGIN
SET NOCOUNT ON;
SELECT
comp_name, p_center, branch_id, xcomp_name, xp_center, xbranch_id
FROM
tbl_company B
INNER JOIN
tbl_b_office X ON X.batch_id = B.tran_id
WHERE
X.office_stat = 1
OR
(
X.office_stat = 0
AND MONTH(X.post_dt) = MONTH(GETDATE())
AND YEAR(X.post_dt) = YEAR(GETDATE())
)
ORDER BY
comp_name ASC;
END
Then in the code, check the value of office_stat and continue accordingly.