I want to add +1 for views column when a visitor view a page. I decided to make it using trigger, but i don't know how to make a trigger on select, I see examples on delete, update and insert but no one mentioned select. anyone can help me with simple example?
There is no such thing as a trigger for 'SELECT' in SQL Server. As an alternative you could create a stored procedure that does the SELECT and UPDATEs your view counts.
short answer is no,there is nothing like trigger on SELECT.moreover
If the data you have if so sensitive and you want to implement access audit in t-sql (which not the best design idea), you can do the following:
Remove SELECT access to the table from all users
Create stored procedure to retrieve data from the table
Implement custom audit inside of the above stored proc.
you can view this link here to read about it more
Related
Basically what I'm trying to do is create a dynamic trigger where if a table from database 1 has a new record inputed. if it falls in the category of data that I need for database 2, it automatically populates the table in database 2 without me needed to manually update.
Right now I am going into the table in database 1 sorting for the category I need and copying the data I need into the table in database 2.
I tried to make this process easier by doing a select query for the columns that I need from database 1 to database 2, which works fine however it overwrites what I have already and I have to basically recreate everytime.
So after all that rambling I guess exactly what I need to know. Is there a way to create a trigger that if a new line item is inputed in database 1 with the tag matching the type of material I need to transfer to database 2. Also on top of that I only need to transfer 2 columns from database 1 to database 2.
I would try to post a sample code, however I have no idea where to start on this.
I suggest you look into Service Broker messaging. We use it quite a bit and it works quite well. You can send messages to the other database with the data that needs to be inserted and allow the second database to do all the work. This will alleviate the worries about the second database being offline or causing an error which rolls back into your trigger. If the second database is unavailable the messages will queue up in your database until it can send them. This isn't the easiest thing to set up but is a way to keep the two databases from being so closely tied together.
Service Broker
I am unclear about the logic in your selection but if you want to save a copy of what was just inserted into table1 into a table (table2) on another database, using a trigger, you can try this:
create trigger trig1 on dbo.table1
after insert as
insert into database2.dbo.table2 (col1,col2,col3) values (inserted.col1, inserted.col2)`
You could use an AFTER INSERT Trigger like this:
CREATE TRIGGER [FirstDB].[dbo].[YourTrigger]
ON [FirstDB].[dbo].[Table]
AFTER INSERT
AS
BEGIN
INSERT INTO [OtherDB].[dbo].[Table] SELECT (values...)
END
I recommend you consider non-trigger alternatives as well though. Cross-DB triggers could be risky (what if the other db is offline, etc.)
are we using SQL Server Views for only Getting(SELECT) the Results or is there any other operations can be performed by using VIEWS.
My Question is i am Trying to Insert some New Records into my table by using Views, is it possible to do this operation by using this Views.
You can, in fact, insert, update or delete using a View. From MSDN:
You can modify the data of an underlying base table through a view, in
the same manner as you modify data in a table by using UPDATE,
INSERT and DELETE statements or by using the bcp utility and BULK INSERT statement.
However, there are restrictions on how you can actually do this. You can read the details on MSDN. In short, the view must only reference columns from one base table, must not contain any computed or derived columns and must not contain grouping clauses.
No, a view is a "virtual table", so you can't execute operations like insert and update.
You have to apply the changes into the original table then the view will reflect the changes.
View
If you are using MS SQL Server, you can use "Stored Procedure". Or similar in other DBMS.
I am trying to create a generic trigger in SQL Server which can copy all column data from Table A and insert them in corresponding fields in Table B.
There are few problems I am facing.
I need this copy to occur under three conditions : INSERT, DELETE and UPDATE.
The trigger needs to be triggered after CUD operations. using AFTER throws SQL error saying ntext etc are not supported in inserted. How do I resolve this error?
Instead of if used can work for INSERT but not for delete. Is there a way to do this for delete operations?
Is there a way I can write a generic code inside the trigger which can work for all sorts of tables (we can assume that all the columns in table a exists in column b)
I am not well versed with triggers or for that matter DDL in SQL Server.
Appreciate if some can provide me some solutions.
Thanks
Ben
CREATE TRIGGER (Transact-SQL)
Use nvarchar(max) instead of ntext.
You can have an instead of trigger for delete.
You can have one trigger that handles insert/update/delete for one table but you can not connect a trigger to more than one table.
I am using a trigger in PostgreSQL 8.2 to audit changes to a table:
CREATE OR REPLACE FUNCTION update_issue_history() RETURNS trigger as $trig$
BEGIN
INSERT INTO issue_history (username, issueid)
VALUES ('fixed-username', OLD.issueid);
RETURN NULL;
END;
$trig$ LANGUAGE plpgsql;
CREATE TRIGGER update_issue_history_trigger
AFTER UPDATE ON issue
FOR EACH ROW EXECUTE PROCEDURE update_issue_history();
What I want to do is have some way to provide the value of fixed-username at the time that I execute the update. Is this possible? If so, how do I accomplish it?
Try something like this:
CREATE OR REPLACE FUNCTION update_issue_history()
RETURNS trigger as $trig$
DECLARE
arg_username varchar;
BEGIN
arg_username := TG_ARGV[0];
INSERT INTO issue_history (username, issueid)
VALUES (arg_username, OLD.issueid);
RETURN NULL;
END;
$trig$ LANGUAGE plpgsql;
CREATE TRIGGER update_issue_history_trigger
AFTER UPDATE ON issue
FOR EACH ROW EXECUTE PROCEDURE update_issue_history('my username value');
I don't see a way to do this other than to create temp tables and use EXECUTE in your trigger. This will have performance consequences though. A better option might be to tie into another table somewhere and log in who logs in/out by session id and back-end PID, and reference that?
Note you don't have any other way of getting the information into the update statement. Keep in mind that the trigger can only see what is available in the API or in the database. If you want a trigger to work transparently, you can't expect to pass information to it at runtime that it would not have access to otherwise.
The basic question you have to ask is "How does the db know what to put there?" Once you decide on a method there the answer should be straight-forward but there are no free lunches.
Update
In the past when I have had to do something like this when the login to the db is with an application role, the way I have done it is to create a temporary table and then access that table from the stored procedures. Currently stored procedures can handle temporary tables in this way but in the past we had to use EXECUTE.
There are two huge limitations with this approach. The first is that it creates a lot of tables and this leads eventually to the possibility of oid wraparound.
These days I much prefer to have the logins to the db being user logins. This makes this far easier to manage and you can just access via the value SESSION_USER (a newbie mistake is to use CURRENT_USER which shows you the current security context rather than the login of the user.
Neither of these approaches work well with connection pooling. In the first case you can't do connection pooling because your temporary tables will get misinterpreted or clobbered. In the second, you can't do it because the login roles are different.
Update: My problem doesn't seem to be with the SQL server. I executed an update statement inside the database manually against the view and I was able to update the Bar table. I'll close this and research the OleDbDataAdapters more since I think the problem lies with them.
This question applies to MS SQL Server 2000. How do I determine which table of the multitable view can be modified?
I have the following view:
CREATE VIEW dbo.MyView
AS
SELECT dbo.Foo.Id, dbo.Bar.Id, dbo.Foo.column1, dbo.Foo.column2,
dbo.Foo.column3, dbo.Bar.column1, dbo.Bar.column2,
dbo.Bar.column3
FROM dbo.Bar INNER JOIN
dbo.Foo ON dbo.Bar.Id = dbo.Foo.ForeignId
When I update this view, (using VB.NET OleDbDataAdapters), I can update columns of Foo, but not columns of Bar. My investigation into this tells me that in a multitable view like this that MS SQL server only allows you to update one of the tables. So my question is, how does SQL server determine which table can be updated?
I tried a test where I edit the fields of a particular row from the view. Afterwards, I used the OleDbDataAdapter to update the view. Only the edits to the Foo table were accepted. The edits to the Bar table were ignored (no exception thrown).
Is there a way to predict which of the tables can be updated or a way to control which one? What if I wanted Bar to be the updateable table instead of Foo?
Update: I found this on google, MS SQL Server 2000 Unleased:
http://books.google.com/books?id=G2YqBS9CQ0AC&pg=RA1-PA713&lpg=RA1-PA713&dq=ms+sql+server+"multitable+view"++updated&source=bl&ots=ZuQXIlEPbO&sig=JbgdDe5yU73aSkxh-SLDdtMYZDs&hl=en&ei=b-0SSq-aHZOitgPB38zgDQ&sa=X&oi=book_result&ct=result&resnum=1#PRA1-PA713,M1
(For some reason the URL I'm trying to paste doesn't work with this site, sorry that you have to copy&paste.)
Which says:
An update through a multitable view cannot affect more than one underlying base table.
A delete cannot be executed against multitable views.
But, I don't yet see an answer to my question.
Again, my question is:
How do I determine which table of the multitable view can be modified?
I realize I can write two update statements one for each table. My concern is different. I need to audit code that uses views like the one above and does updates on the views. I was hoping to find a way to determine which parts of the updates will be silently ignored.
Example:
I edit Bar.Column1 and then call the Update() method of the OleDbDataAdapter. This results in the Bar table not being modified nor is an exception thrown. If I edit Foo.Column2 then call Update() the Foo table does get modified.
You can update any table in the view, but only fields that are all in the same table in that statement. If you need to update fields from two tables in a view, then you must write two update statements.
Personally I prefer not to update or delete from views at all. I use the base tables for that.
There are also rules concerning whether view is updateble. See Books online. Search for this:
views-SQL Server, modifying data
You need to be able to uniquely identify the row in the table by returning the primary key. Try returning dbo.Bar.Id in the view, and you should be able to edit columns in table Bar.