I am using JOIN command to connect two tables in SqlDataSource.
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:CS %>"
SelectCommand="SELECT UserName as UN, AboutMe, WebPage, Email FROM Users JOIN ProfileImages ON ProfileImages.UserName = Users.UN WHERE (UN = #UserName)" >
</asp:SqlDataSource>
In MS SQL Server Management Studio this command is ok. But in the SqlDataSource it return errors - Invalid column name 'UN', Ambiguous column name 'UserName'
How do I alias this command right in SqlDataSource to not return these errors?
Your query is a bit wrong
You used alias i a wrong way
First:
You can use alias in the following sections:
Fields. Example Username as UN
Tables names: UserTable as US
In the order by section example: Order BY UN Desc
This because the sql runs the query operations in the following sequence:
FROM clause
WHERE clause
GROUP BY clause
HAVING clause
SELECT clause
ORDER BY clause
So because the FROM clause runs first the sql doesn't know about the alias in the SELECT clause
Take a look on a correct query
SELECT
UserName as UN,
AboutMe,
WebPage,
Email
FROM Users
JOIN ProfileImages ON ProfileImages.UserName = Users.UserName
WHERE (Users.UserName = #UserName)
I'm not an expert at SQL, but if both ProfileImages and Users contain the column 'UserName', then in your select columns you need to specify the table from which the UserName is pulled. So something like:
SELECT Users.UserName as UN, Users.AboutMe, Users.WebPage, Users.Email
FROM Users
JOIN ProfileImages ON ProfileImages.UserName = Users.UserName
WHERE (Users.UserName = #UserName)
You cannot use the column alias in the where clause.
SELECT UserName as UN, AboutMe, WebPage, Email
FROM Users usersAlias JOIN ProfileImages piAlias ON piAlias.UserName = usersAlias.UserName
WHERE (usersAlias.UserName = #UserName)
It makes sense when you look at the order of execution:
http://blog.sqlauthority.com/2009/04/06/sql-server-logical-query-processing-phases-order-of-statement-execution/
Since the order of execution is:
These phases and their orders are given as follows:
FROM
ON
OUTER
WHERE
GROUP BY
CUBE | ROLLUP
HAVING
SELECT
DISTINCT
10 ORDER BY
TOP
When these are being processed (the "from" (#1) and "on" (#2) and "where" (#4))..they have no knowledge about the "select" (#8) (aka, the alias name for UN), the column alias in the select clause cannot be used in the WHERE and FROM (and ON) clauses.
Related
I have a schema which uses a compound primary key to store users and associated data, like so:
CREATE TABLE users (
domain integer,
userid integer,
...
PRIMARY KEY (domain, userid)
);
CREATE TABLE userdata (
domain integer,
userid integer,
key integer,
...
PRIMARY KEY (domain, userid, key),
FOREIGN KEY (domain, userid) REFERENCES users(domain, userid)
);
I cannot make changes to this schema, nor can I opt to use another DBMS.
I want to delete some rows in userdata, based on a criterion over users. Conceptually, i'd like to do something like:
DELETE FROM userdata
WHERE (domain, userid) IN (
SELECT domain, userid FROM users WHERE <some condition>
) AND key = some_constant;
Or alternatively
DELETE ud FROM userdata ud
INNER JOIN users u on u.domain = ud.domain and u.userid = ud.userid
WHERE <some condition over u>
AND ud.key = some_constant
But sqlite3 (3.8.2) rejects both forms, the former with
Error: near ",": syntax error
and the latter with
Error: near "ud": syntax error
Annoyingly, the IN syntax works perfectly well when the join key consists of a single column.
What is the proper syntax or technique for achieving this ?
Not a SQLite user but I'd try selecting the ROWIDs to delete in userdata. I mean something like
delete from userdata
where rowid in (
select ud.rowid
from userdata ud
join users u on ...
where condition
)
I am supposing you want to delete key from user_data and x,y,z condition on user.
DELETE ud.key FROM user_data AS ud
LEFT JOIN users AS u ON ud.user_id = u.user_id
WHERE u.something='condition'
Your first attempt does not work because tuples (or whatever they are called) are not supported by SQLite (supported syntax here).
Your second attempt is invalid syntax as there is no JOIN in DELETE statements (maybe as an extension introduced by some DBMS but not in SQL92 apparently).
What you can try instead is:
DELETE FROM userdata
WHERE domain IN (SELECT u.domain FROM users u WHERE <some condition>)
AND userid IN (SELECT u.userid FROM users u WHERE <some condition> AND domain = u.domain)
AND key = some_constant;
Select pmtblempreg.Id
,pmtblempreg.Name
,pmtblempreg.UserName
,pmtbldesignation.Designation
, pmtblempreg.skypeid
,pmtblempreg.EmailId
From pmtbldesignation
Right join pmtblempreg ON
pmtbldesignation.Id = pmtblempreg.DesignationId
This query works fine in oracle database. But when executing using sqlDataSource for populating a gridview an error is showing that invalid table name
when i execute it through the query builder of sqldataSource the query changes to
SELECT PMTBLEMPREG.ID
,PMTBLEMPREG.NAME
,PMTBLEMPREG.USERNAME
,PMTBLDESIGNATION.DESIGNATION
,PMTBLEMPREG.SKYPEID
,PMTBLEMPREG.EMAILID
FROM { **oj PMTBLDESIGNATION**
RIGHT OUTER JOIN PMTBLEMPREG ON
PMTBLDESIGNATION.ID = PMTBLEMPREG.DESIGNATIONID
}
an oj is automatically created along with the table name.
Is that the problem??
Try like this
Just Use this code in CodeBehid
Dim SQLStatement As String = "Select pmtblempreg.Id,pmtblempreg.Name,pmtblempreg.UserName ,pmtbldesignation.Designation, pmtblempreg.skypeid,pmtblempreg.EmailId From pmtbldesignation
Right join pmtblempreg ON pmtbldesignation.Id = pmtblempreg.DesignationId"
sqldatsrc.ConnectionString = ConnectionString
sqldatsrc.SelectCommand = SQLStatement
Or Paste the query in SQLDatasource Select Command as
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="Data Source=xx;User ID=xx;Password=xxx" ProviderName="xx" SelectCommand="Select pmtblempreg.Id,pmtblempreg.Name,pmtblempreg.UserName ,pmtbldesignation.Designation, pmtblempreg.skypeid,pmtblempreg.EmailId From pmtbldesignation
Right join pmtblempreg ON pmtbldesignation.Id = pmtblempreg.DesignationId"></asp:SqlDataSource>
SELECT PE.ID
,PE.NAME
,PE.USERNAME
,PD.DESIGNATION
,PE.SKYPEID
,PE.EMAILID
FROM PMTBLDESIGNATION PD
RIGHT OUTER JOIN PMTBLEMPREG PE ON
PD.ID = PE.DESIGNATIONID
where PD is the Table name alias for PMTBLDESIGNATION and PE is the Table name alias for PMTBLEMPREG
Updated:
By default if you execute the query it checks the table in the Master Database
Instead before executing query Write this code
Use Your_database_name
The database name is where the tables are placed.
Try this
Hope this Helps
I am trying to log all the changes to database but was unable to find a way to get current username to the trigger. I have triggerData table which stores the information of user
(guid (userid), data (username), logintime) these are inserted when user sign in.
Here is the trigger
declare #UserIsOnlineTimeWindow DateTime
declare #currenttime DateTime
set #currenttime = GETDATE()
set #UserIsOnlineTimeWindow = 10
DECLARE #uname nvarchar(max)
**set #uname = (SELECT T.UserName from (SELECT distinct u.UserName FROM aspnet_Users u
WHERE IsAnonymous = 'FALSE' AND ((#currenttime - #UserIsOnlineTimeWindow) < u.LastActivityDate)) as t,
TriggerData td, aspnet_Users au
WHERE t.UserName = td.Data and td.guid = au.UserId and td.logintime = (select MAX(td.logintime) from TriggerData td))**
DECLARE #ComputerName nvarchar(50)
DECLARE #IPAddr nvarchar(50)
DECLARE #BroadcastIP nvarchar(50)
DECLARE #auditInsert nvarchar(255)
SET #ComputerName = (SELECT ComputerName FROM inserted)
SET #IPAddr = (SELECT ISNULL(IPAddr,0) FROM inserted)
SET #BroadcastIP = (SELECT ISNULL(BroadcastIP,0) FROM inserted)
SET #auditInsert = #ComputerName+' '+#IPAddr+' '+#BroadcastIP
Begin
INSERT INTO Audit(OldInfo ,NewInfo,[User],Date1,Type,TableName) VALUES('New Record',#auditInsert, #uname ,GETDATE(),'Added','LabIP')
End
The query for the username does not give the currently modifying user instead it gives the recently logged in user. Any help is appreciated. Thanks!
Like marc_s said triggers can and will be applied once per batch. In your case however it sounds like your current application is only inserting once per batch so it's working fine. Your will have a problem however if anyone tries to insert more than one row. Say from another part of the application, or from a query window. It's really up to you if you want to fix it now or wait for it to break (if ever).
I've re-formated the query that is giving you problems.
set #uname = (SELECT T.UserName FROM
(SELECT DISTINCT u.UserName
FROM aspnet_Users u
WHERE IsAnonymous = 'FALSE'
AND ((#currenttime - #UserIsOnlineTimeWindow) < u.LastActivityDate)) AS t
JOIN TriggerData td
ON t.UserName = td.Data
JOIN aspnet_Users au
ON td.guid = au.UserId
WHERE td.logintime = (select MAX(td.logintime) from TriggerData td))
You can see from this where your problem is. If you look in the WHERE clause you will see that you are specifically pulling the row that last logged in. If you are not using an application id (although it sounds like you are) you can use USER_NAME() or SUSER_SNAME() to pull the current user. Unfortunatly based on the information you have provided I don't think you will be able to pull the user that actually made the change, again assuming that you are using an application id.
You might try putting the SPID (id for the current connection) into your users table. You can retrieve this as ##SPID. That way while you are in the current connection you will always be able to tell who the current user is. Of course this will only work if you are holding onto the connection for the whole time the user is logged in (probably not in a web based application).
Last (and unfortunatly least) is rather than using triggers create stored procedures to do your inserts. Pass in the current user into the SP as part of the parameter list and do your logging there.
Sorry I couldn't help more.
How do I count the number of columns in a table in sql and display this value in web page (aspx) ?
for example , i want to get the number of ID filed in sql server to display in a web page for understand how many people are member on my web site
thanks
Do you mean 'count the number of rows?'
If so something like select count(id) from member_table will give you the amount of members
SELECT COUNT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE
TABLE_CATALOG = 'database' AND TABLE_SCHEMA = 'dbo'
AND TABLE_NAME = 'table'
I am not sure what database you are using but here is MS SQL's version.
MSSQL Count Columns:
SELECT COUNT(COLUMN_NAME) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_CATALOG = 'database' AND TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'table'
But I suspect you mean Rows?
SELECT COUNT(column_name) FROM table_name
e.g.:
SELECT COUNT(id) FROM users
will return you a number of registered users
How to bind data from two tables.
tbl_user
first name userid
tbl_usermessage
userid timereceived msgid
How to display username and timereceived in datagrid
SELECT TimeReceived, FirstName FROM tbl_usermessage INNER JOIN tbl_user on tbl_usermessage.tbl_user_UserID = tbl_user.UserID WHERE tbl_message_MsgID = #Value1";
This is what I am trying i am getting syntax error. here Time received is from tbl_usermessage and firstname is from tbl_User and both table has userid
How about joining both tables on your sql query?
You need to connect a SqlDataSource to your DataGrid by setting the SqlDataSource's DataSourceID property to the SqlDataSourceID. Set the SqlDataSource's SelectCommand property to the SQL required to get the items:
SelectCommand="SELECT tableone.username, tableone.userid, tabletwo.userid, tabletwo.timereceived
FROM tableone INNER JOIN tabletwo ON tableone.userid=tabletwo.userid"
And also set the ConnectionString property:
ConnectionString="<%$ ConnectionStrings:MyDatabaseConnectionString %>" >
You need to retrieve the data from your database with a SQL Query which JOINs the two tables on a column that is common to both:
Something along these lines:
SELECT
userId, username, timereceived
FROM
Table1 INNER JOIN Table2 ON Table1.userId = Table2.UserID
Here's an example for your reference.