I'm using the FileTables feature and have setup a trigger to populate a FileProperties table whenever a file is copied to the SQL Server file share.
I'm trying to grab the file size (cached_file_size), and I get a value of zero. I set up the trigger the same way a standard FileTable does using DATALENTGH(file_stream). The code below is using the inserted tables' file_stream:
ALTER TRIGGER [dbo].[FileTable_Insert_Trigger]
ON [dbo].[Files]
AFTER INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #s_id UNIQUEIDENTIFIER,
#fs VARBINARY(MAX),
#nm NVARCHAR(255),
#fp NVARCHAR(MAX),
#cfs BIGINT,
#ft NVARCHAR(255);
SELECT #s_id = ins.stream_id FROM inserted ins;
SELECT #fs = ins.file_stream FROM inserted ins;
SELECT #nm = ins.name FROM inserted ins;
SELECT #fp = ins.file_stream.GetFileNamespacePath() FROM inserted ins;
SELECT #ft = ins.file_type FROM inserted ins;
SELECT #cfs = DATALENGTH(#fs);
INSERT INTO [FileProperties] (stream_id, [name], filepath, file_type,
cached_file_size, DateAdded, UserID)
VALUES (#s_id, #nm, #fp, #ft,
#cfs, CURRENT_TIMESTAMP, 1);
END
I've also tried grabbing the computed value directly from the FileTable:
SELECT #cfs = Files_1.cached_file_size
FROM [dbo].Files AS Files_1
WHERE Files_1.stream_id = #s_id;
Still getting zero. What am I missing here? Thank you.
[EDIT] I tried playing around with getting the DATALENGTH of other values such as the name (#nm) and stream_id (#s_id) and I do get the values correctly.
Related
I'm trying to write a stored procedure to modify a session in my Sessions table. I need to be able to insert values into a specified row i.e. with a condition included although I'm not sure how.
Here is my code (I'm aware that I cannot do INSERT INTO > VALUES > WHERE but I'm trying to give you an idea of what I want to do).
CREATE PROCEDURE [dbo].[TT_Modify_Session]
#SessionName NVARCHAR(50),
#TrainingName NVARCHAR(100),
#Trainee NVARCHAR(20),
#TrainingDate DATE,
#SessionID INT
AS
SET NOCOUNT ON;
BEGIN TRY
BEGIN TRAN
INSERT INTO dbo.TT_Sessions (SessionName, Trainee, TrainingDate, TrainingName)
VALUES #SessionName, #Trainee, #TrainingDate, #TrainingName
WHERE #SessionID = [SessionID]
COMMIT
END TRY
BEGIN CATCH
ROLLBACK
PRINT ERROR_MESSAGE()
END CATCH
RETURN #sessionID
Any help is greatly appreciated!
You describe code to "modify" values that already exist in the table. That's an UPDATE...
(INSERT adds a new row to a table, and leaves all pre-existing rows as they were...)
UPDATE
dbo.TT_Sessions
SET
SessionName = #SessionName,
Trainee = #Trainee,
TrainingDate = #TrainingDate,
TrainingName = #TrainingName
WHERE
SessionID = #SessionID
I have one table which consists of one trigger which will be called if any insert or update operation performed on that table.
This trigger will insert a new row in other physical table.
First I am taking the entire data to be inserted into a temporary table and then I am inserting data into my physical table(which has trigger).
After performing insert operation all the records in the temporary table are getting inserted into physical table but the trigger is executing for only first record, for rest of the records it is not executing.
Can anyone please help me with this issue.
NOTE : With cursor it is working fine but for performance issue I don't want to use cursor.
ALTER TRIGGER [dbo].[MY_TRG]
ON [dbo].[T_EMP_DETAILS]
FOR INSERT , UPDATE
AS
BEGIN
IF UPDATE(S_EMPLOYEE_ID)OR UPDATE(S_GRADE_ID)OR UPDATE(D_EFFECTIVE_DATE) OR UPDATE(S_EMPLOYEE_STATUS)
BEGIN
DECLARE #EmpId varchar(6)
DECLARE #HeaderId Int
DECLARE #FYStartYear varchar(4)
DECLARE #EffDate Smalldatetime
DECLARE #UpdatedBy varchar(10)
DECLARE #ActionType varchar(1)
DECLARE #RowCount Int
DECLARE #EmpRowCount Int
DECLARE #AuditRowsCount Int
DECLARE #EMP_STATUS VARCHAR(1)
DECLARE #D_FIN_START_YEAR DATETIME
DECLARE #Food_Count int
SELECT #FYStartYear = CAST(YEAR(D_CURRENT_FY_ST_DATE)AS VARCHAR) FROM dbo.APPLICATION WHERE B_IS_CURRENT_FY = 1
SELECT #UpdatedBy = 'SHARDUL'
select #EmpId = S_EMPLOYEE_ID from inserted
select #HeaderId = N_HEADER_TXN_ID from inserted
select #EffDate = D_EFFECTIVE_DATE from inserted
select #FLEXI_AMT = N_FLEX_BASKET_AMT from inserted
select #EMP_STATUS = S_EMPLOYEE_STATUS from inserted
select #D_FIN_START_YEAR=D_FIN_START_DATE from inserted
SELECT #RowCount = count(*) from T_EMP_DETAILS
WHERE S_EMPLOYEE_ID = #EmpId and
SUBSTRING(CAST(D_EFFECTIVE_DATE AS VARCHAR),1,11) = SUBSTRING(CAST(#EffDate AS VARCHAR),1,11)
BEGIN
exec INSERT_DEFAULT_VALUES #EmpId,#HeaderId,#UpdatedBy
END
That's one of many reasons Bulk is so fast :). Read Bulk Insert syntax and you'll see FIRE_TRIGGERS parameter. Use it.
As I wrote in my comment - you are using inserted in improper way. As written now it will work only for 1 row.
The second one is a WEIRD number of variables, and only few are used, why?
Third - you are using SP in the end of batch, you need to post it's code, I bet there is some insert in it, maybe you could avoid using this SP and insert directly in some table from inserted.
I am a beginner with SQL and I'm trying to create a trigger to fire with an IF statement. Below is the trigger:
CREATE TRIGGER [Vector].[trg_insert_id]
ON [vector].[a69]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #OID int
SELECT #OID = OBJECTID FROM INSERTED
DECLARE #siteID float
SELECT #siteID = MAX([SiteID]) FROM [vector].[a69]
SELECT #siteID
IF #OID NOT IN(select OBJECTID from vector.a69)
BEGIN
UPDATE [vector].[a69]
SET SiteID = #siteID + 0.00001
WHERE OBJECTID IN (#OID)
END
END
What I'm trying to have the trigger do is, after an insert to the table, search to see if the inserted OBJECTID already exists in the table. If it does not, update SiteID field by 0.00001.
When I have the IF statement, the trigger does not work. If I remove the IF statement, the trigger works, but it increments the SiteID field for other records with the same OBJECTID.
Any suggestions on what I'm doing wrong?
NOT IN can be dangerous to use. If the subquery returns even a single NULL value, then the results is never true. This may be the cause of your problem. One simple fix is:
IF #OID NOT IN (select OBJECTID from vector.a69 where OBJECTID is not null)
. . .
I think a better approach is to use NOT EXISTS:
IF NOT EXISTS (select 1 from vector.a69 where OBJECTID = #OID)
Might as well learn to use triggers correctly. First, if you ever find yourself writing something like:
DECLARE #OID int
SELECT #OID = OBJECTID FROM INSERTED
then your trigger is broken . It must be able to handle multiple values in the inserted or deleted pseudo-tables:
Next this part doesn't make logical sense
IF #OID NOT IN(select OBJECTID from vector.a69)
BEGIN
UPDATE [vector].[a69]
SET SiteID = #siteID + 0.00001
WHERE OBJECTID IN (#OID)
END
IF #OID doesn't exist in table vector.a60 then you can't update it. I am partly guessing what you want to do but I think this is what you actually want in the trigger.
CREATE TRIGGER [Vector].[trg_insert_id]
ON [vector].[a69]
FOR INSERT
AS
BEGIN
SET NOCOUNT ON;
UPDATE [vector].[a69]
SET SiteID = #siteID + 0.00001
WHERE OBJECTID IN (SLECT OID FROM inserted)
END
I might have looked on this too long, so i hope someone can help me out here.
i'm playing around with comparing files metadata to identify unique data chunks, and thereby detect deduplication potential... here goes.
drop proc insertFile
go
create proc [dbo].[insertFile] #fileHash char(64), #name varchar(200)
as
set nocount on;
declare #fileId int
declare #klientId int
set #klientId = (SELECT cast(RAND() * 10 + 1 as int))
IF NOT EXISTS (select * from data_file where hash_key = '#fileHash')
begin
insert into data_file (hash_key) values (#fileHash)
end
set #fileId = (select id from data_file where hash_key = '#fileHash')
insert into klient_file (data_file, klient, name) values (#fileId, #klientId, #name)
there is a unique constraint on hash_key and this is violated when i enter a value that exists, this should not happen, the IF checks if it exist, and should only insert if the hash value does not.
the data should enter klient_file no matter what...
again, the error is the violation of the unique constraint, that should have been avoided with the IF check, the IF works by its own, just not in the procedure. any thoughts?
(this all runs on a localdb instance)
You have your parameter within quote marks in the EXISTS check, so in this line
IF NOT EXISTS (select * from data_file where hash_key = '#fileHash')
you are checking if '#fileHash' exists, not the actual value assigned to the parameter, so even if the hash_key exists you are trying to insert it because '#FileHash' does not exist in the table
Your procedure should be:
create proc [dbo].[insertFile] #fileHash char(64), #name varchar(200)
as
set nocount on;
declare #fileId int
declare #klientId int
set #klientId = (SELECT cast(RAND() * 10 + 1 as int))
IF NOT EXISTS (select * from data_file where hash_key = #fileHash)
begin
insert into data_file (hash_key) values (#fileHash)
end
set #fileId = (select id from data_file where hash_key = #fileHash)
insert into klient_file (data_file, klient, name) values (#fileId, #klientId, #name)
I created a stored procedure that should do 2 inserts in one
First step I want to create a new entry per insert into.
Second step I will catch the created Id from this entry
Third step I want to copie multiple entries per select from one table and insert those to the same table with the Id
Create PROCEDURE dbo.Rolle_Copie
#Id as int,
#newId as int = 0,
#Name AS nvarchar(50)
AS
INSERT INTO Rollen (RolleName)
VALUES (#Name)
#newId = SCOPE_IDENTITY()
INSERT INTO Berechtigung_Rolle (RefRolleId,RefBerechtigungId)
SELECT
RefBerechtigungId, #newId
FROM
Berechtigung_Rolle
WHERE
RefRolleId = #Id
RETURN
but I get an error
Wrong syntax next to #newId
Could somebody please enlight me what's wrong?
Any advice is greatly appreciated
don't forget to use SET
SET #newId = SCOPE_IDENTITY()