Showing posts with label columns. Show all posts
Showing posts with label columns. Show all posts

Thursday, March 29, 2012

Granting UPDATE for only certain columns in a table

I have tried using the SQL statement shown below to grant UPDATE permissions for a single column in a single table to a user with db_datareader privileges.

grant update (col_1) on trs.dbo.table_1 to calc

When I then run a SQL script that has an UPDATE for col_1 on trs.dbo.table_1, I get an error message

Msg 230, Level 14, State 1, Line 2100

UPDATE permission denied on column 'col_2' of object 'table_1', database 'TRS', schema 'dbo'.

Why is the error message referring to "col_2" when my SQL statement is trying to update "col_1"?

When I performed the "grant" I did it with an account that has db_owner, db_securityadmin, and db_ddladmin privileges.

This worked in SQL Server 2000. What must I do to get it to work in SQL Server 2005?

Sorry Dan - can you show us the update query?|||

You are going to have to dig deeper. The only scenario that I can think of where an update to another column causes an update to another column causing issues like this is with a trigger with dynamic SQL (a real no-no in almost all cases, but it could exist). The fact that you have appended database names to the ddl makes me curious as to how that *might* cause issue, but I don't even see how anything cross-database could be an issue either.

Here is a script that shows what I am meaning:

create table test
(
column1 int,
column2 int
)
go
create user fred without login
go
execute as user = 'fred'
go
update test
set column1 = 1
/*
Msg 229, Level 14, State 5, Line 1
The UPDATE permission was denied on the object 'test', database 'tempdb', schema 'dbo'.
*/
go
revert
go
grant update (column1) on test to fred
go
execute as user = 'fred'
go
update test
set column1 = 1
/*
(0 row(s) affected)
*/
update test
set column2 = 1
/*
Msg 230, Level 14, State 1, Line 1
The UPDATE permission was denied on the column 'column2' of the object 'test', database 'tempdb', schema 'dbo'.
*/
go
revert
go
create trigger test$updateColumn1
on test
after update
as
begin
exec('
update test
set column2 = 2')
end
go
execute as user = 'fred'
go
update test
set column1 = 1
/*
Msg 230, Level 14, State 1, Line 2
The UPDATE permission was denied on the column 'column2' of the object 'test', database 'tempdb', schema 'dbo'.
*/

If you could post a full example like this showing your issue I think that you might find your error, or certainly one of us can help you out.

|||

Thanks for your support.

Here is a small bit of code that is able to produce the problem. It seems to be associated with having a JOIN in the UPDATE statement. An UPDATE without the JOIN works just fine.

Using a DB_OWNER account perform the following table creation, insert, and grant commands:

create table trs.dbo.people
(
name varchar(10),
sex varchar(10),
age smallint
)

insert into people values ('tom', 'male', 10)
insert into people values ('jane', 'female', 18)
insert into people values ('sue', 'female', 22)

create table trs.dbo.grads
(
name varchar(10),
grad_yr varchar(4)
)

insert into grads values ('jane', '2006')
insert into grads values ('sue', '2002')

grant update (age) on trs.dbo.people to calc

Then, from the db_datareader account, calc, run the following UPDATE statements, one at a time.

update p
set age = 40
from trs.dbo.people p
where (age is not null)
;

update p
set age = 35
from trs.dbo.people p
inner join trs.dbo.grads g
on p.name = g.name
where (age is not null)
;

The first one works. The second one fails with error message

Msg 230, Level 14, State 1, Line 1

UPDATE permission denied on column 'name' of object 'people', database 'TRS', schema 'dbo'.

Does this help?

|||Very nice. I have no answer as to why this is, but I will check around and let you know.|||Thanks!|||Do you have select permission on the other columns?

I know it's complaining that you don't have UPDATE permission... but it's complaining about your access to another column that's involved in the join.

Rob|||

Rob,

If I enter SELECT statements against the two tables, while connected as "CALC", all the rows from each table are returned.

select * from grads;

select * from people;

I have also tried using the DB_OWNER connection to explicity GRANT SELECT access to those tables, and still get the same error message when I try to update the AGE column, as in the example above, while connected as "CALC".

grant select on trs.dbo.people to calc
grant select (name) on trs.dbo.people to calc
grant select on trs.dbo.grads to calc

Dan

|||Ok, so that idea wasn't right. ;)

It's somehow related to the fact that you're joining the table you're updating to another table, and the engine thinks that it needs to be able to update that column too. It doesn't of course, but the fact that the column is used in the query must be confusing it somehow.

I assume this works just fine if you grant update access to the name column too?

One workaround might be to wrap it up in a table expression, but if that works, it'll just be down to luck.

Rob|||

The same code runs just fine with SQL Server 2000. I only ran into a problem when I tried moving it over to SQL Server 2005.

If I grant UPDATE access on the NAME column, as identified in the Error message, then the code runs.

But I hate to do that, since CALC is supposed to be a relatively "unprivileged" user, with db_datareader general privileges only, and CREATE TABLE privileges -- and in my actual application, these other columns are the PRIMARY KEY columns in the tables.

Adding a new column to the table, a column to which CALC has UPDATE permission, was a way of avoiding creating an entirely new table for CALC to own, with 500,000 rows, and a 20-byte primary key that incorporates 5 columns. Had I created such a new table my processing queries would have to JOIN this table to the 500,000 row counterpart. Instead of such a JOIN I added a new column as a simpler, faster solution.

Dan

|||Hmm... I'll have to do some more hunting. I'd like to say "try using a cte or view", or something like that (based on the fact that you might be able to update a view without it thinking it needs to be able to update the joining column), but I actually don't know if that will help. I'll have to recreate the situation locally and try some things.

But hopefully some of the other guys will already know the answer to this.

Rob|||

This seems like such a "natural" thing to have to do, in most any application that requires user permissions to only certain columns in a table.

Consider a table that connects salary to social security number. If you want to allow someone to edit SALARY, must you also allow them to edit SOCIAL SECURITY NUMBER?

What if you are running a medical office and have some sort of PATIENT NUMBER in the medical records. If you want to edit information on their account, such as their ZIP CODE, must you also allow them to edit the PATIENT NUMBER?

Is there maybe a greater need in SQL Server 2005 to create a new ROLE for every different set of permissions that one might need in the database, rather than use GRANT UPDATE to customize access to different users?

I'm not now at my office where I could try it, but I'm wondering if some SYSTEM table stores UPDATE permissions, and if a user has NOT received GRANT or DENY UPDATE permissions on a column in a table, maybe an INNER JOIN is being used, rather than an OUTER JOIN on the permissions table. If that is true, I suppose I can DENY UPDATE on the NAME column in the example, and the query should work, because it finds an entry in the permissions table for the NAME column, even though that entry is "DENY." So tomorrow at the office I'll try DENY UPDATE (name) on TRS.DBO.PEOPLE to CALC. (I'll have to check the syntax on the DENY statement. I think I noticed one in the past few days.)

Dan

|||

This is almost clearly a bug that I posted here: https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=257897

A (not terribly satisfying) workaround is to move the join to a subquery:

update p set age = 35
from trs.dbo.people p
where p.name in (select p2.name
from trs.dbo.people p2
inner join trs.dbo.grads g
on p.name = g.name
where (age is not null))

Here is the simple repro with users I posted:

create database trs
go
use trs
go
create table trs.dbo.people
(
name varchar(10),
sex varchar(10),
age smallint
)

insert into people values ('tom', 'male', 10)
insert into people values ('jane', 'female', 18)
insert into people values ('sue', 'female', 22)

create table trs.dbo.grads
(
name varchar(10),
grad_yr varchar(4)
)

insert into grads values ('jane', '2006')
insert into grads values ('sue', '2002')
go
create user calc without login
sp_addrolemember 'db_datareader','calc'
go
grant update (age) on trs.dbo.people to calc
go

--Then, from the db_datareader account, calc, run the following UPDATE
statements, one at a time.
execute as user = 'calc'
go

update p
set age = 40
from trs.dbo.people p
where (age is not null)
;

update p
set age = 35
from trs.dbo.people p
inner join trs.dbo.grads g
on p.name = g.name
where (age is not null)
;

/*
Msg 230, Level 14, State 1, Line 1
The UPDATE permission was denied on the column 'name' of the object
'people', database 'trs', schema 'dbo'.
*/
--

|||

Louis,

Thanks for posting that to the MS "feedback" site.

I tried my "DENY UPDATE" idea, but it didn't fix anything: the same error message was obtained for the same UPDATE statement.

There aren't many places in my code where I am performing updates on columns where the GRANT UPDATE permission is limited to certain columns -- maybe a few dozen. I'll just make the code edits corresponding to your suggestion, and maybe un-do them if/when a patch occurs.

Thanks again.

Dan

|||

Louis,

I reworked my code for SQL Server 2005, using the technique you suggested (or something quite similar):

update p set age = 35
from trs.dbo.people p
where p.name in (select p2.name
from trs.dbo.people p2
inner join trs.dbo.grads g
on p.name = g.name
where (age is not null))

In all but a single instance, this solution worked just fine.

In the remaining instance, the value that I need for the SET clause is from the JOINed table. Were we using the example I supplied (rather than my actual code), this could appear as

update p
set age = cast(g.grad_yr as int) + 18 - 2006
from trs.dbo.people p
inner join trs.dbo.grads g
on p.name = g.name
where (age is not null)

I didn't see any easy way around this, other than to create a CURSOR on "select distinct GRAD_YR from GRADS" and using a LOOP over the CURSOR values, and having code like

update p
set age = @.grad_yr + 18 - 2006
from trs.dbo.people p
where (age is not null) and p.name in (select distinct name from trs.dbo.grads where grad_yr = @.grad_yr)

I am thankful that the number of values for my CURSOR is less than 10, in my actual application.

If you can think of a better alternative, I would be happy to learn of it.

Thanks.

Dan

Tuesday, March 27, 2012

Grant Privileges

I am trying to give limited privileges to a login account on a table, but it
doesn't seem to work. I have a link table in Access 97. Some columns are
supposed to be read only and some columns are supposed to be read-only.
I use the script below
revoke all privileges on stores to shipdirect1
grant update on stores(creditlimit) to shipdirect1
What am I doing wrong?I havn't tested this but you cud always try removing the user and login and
adding it back.
"Arne" wrote:

> I am trying to give limited privileges to a login account on a table, but
it
> doesn't seem to work. I have a link table in Access 97. Some columns are
> supposed to be read only and some columns are supposed to be read-only.
> I use the script below
> revoke all privileges on stores to shipdirect1
> grant update on stores(creditlimit) to shipdirect1
> What am I doing wrong?

Monday, March 19, 2012

Google Like Full Text Search

Hello,

I have a Full-Text Catalog that is populated by various columns in a few different tables. I have been able to create a stored procedure that will search across all of the different full-text columns and return me the results.

My problem is, if the someone searches for
hello world
then to my understanding I want to use FREETEXTTABLE to return my results (I actually get 0 results if I use CONTAINSTABLE)

If someone searches for
"hello world"
then I want to use CONTAINSTABLE because FREETEXTTABLE returns too many results.

And now the biggest problem would be, if someone searches for
"hello world" program
I would somehow need to use CONTAINSTABLE for the phrase and FREETEXTTABLE for 'program'. The SQL to accomplish something like this would probably be very ugly (if possible at all)

Can anyone give me any suggestions on this matter? I'm trying to create a google like search on a database which contains text and files (as BLOBs).

Thanks in advanceI should clarify a bit more.


If someone searches for
"hello world"
then I want to use CONTAINSTABLE because FREETEXTTABLE returns too many results.

The problem isn't that FREETEXTTABLE returns too many results but rather the rankings that I get back aren't helpful. Say I have 2 completely different tables and I want to search across both of them. Table1 has rows that contain the phrase "hello world" while Table2 doesn't contain that specific phrase, but does contain the separate words 'hello' and 'world'. I run FREETEXTTABLE on both Table1 and Table2, Union the results, and then return the table to my web app (where other formatting occurs before the results are displayed to the user.) Unfortunately because of how the Ranks are calculated, the entries in Table2 have a higher Rank than the entries in Table1 (even though the exact phrase occurs in Table1)

I want the rows from Table1 to appear before Table2 in this case.

One solution that I have been playing with is to always use CONTAINSTABLE, use regular expressions to insert 'AND' where applicaple, and use the 'FORMSOF(INFLECTIONAL, @.searchStr)' option. Unfortunately this seems to break when someone searches for
hello world
because I would insert an 'AND' between the words and then try to find the inflectional forms of "hello AND world" which of course breaks.

Once again, and ideas/suggestions would be greatly appreciated|||I think I've found the solution

If someone wants to search for...
"hello world" program

Then the sql would look like this...
SELECT *
FROM CONTAINSTABLE(T_Table, *, 'FORMSOF(INFLECTIONAL, "hello world") AND FORMSOF(INFLECTIONAL, "program")')|||Thanks EvilMonkey - very helpful. =)|||

cool but can u give some details.

Monday, March 12, 2012

Good Question

I have some Lotus Notes files that I saved as Excel spreadsheets. I migrated
the files to SQL using DTS. One of the files has a table with 2 columns as
follows:
Room ID Number of Beds
201 3
202 2
I need to add a column to that table that will look into the combination of
each RoomID and Number Of Beds and will look like this:
Room ID
201A
201B
201C
202A
202B
So, because Room 201 has a capacity of 3 beds, it showed up as 201A, 201B
and 201C and so forth for the other rooms. What code I can use to accomplish
this?
Thanks a million
--
TSUse an auxiliary numbers table.
Example:
use northwind
go
create table t1 (
room_id int not null unique,
number_of_beds int not null check (number_of_beds between 1 and 5)
)
go
insert into t1 values(201, 3)
insert into t1 values(202, 2)
go
select
identity(int, 1, 1) as number
into
number
from
sysobjects as a
cross join
sysobjects as b
go
declare @.s varchar(255)
set @.s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
select
ltrim(room_id) + substring(@.s, n.number, 1)
from
t1
inner join
number as n
on n.number <= t1.number_of_beds
order by
room_id,
n.number
go
drop table t1
go
drop table number
go
AMB
"TS" wrote:

> I have some Lotus Notes files that I saved as Excel spreadsheets. I migrat
ed
> the files to SQL using DTS. One of the files has a table with 2 columns as
> follows:
> Room ID Number of Beds
> 201 3
> 202 2
> I need to add a column to that table that will look into the combination o
f
> each RoomID and Number Of Beds and will look like this:
> Room ID
> 201A
> 201B
> 201C
> 202A
> 202B
> So, because Room 201 has a capacity of 3 beds, it showed up as 201A, 201B
> and 201C and so forth for the other rooms. What code I can use to accompli
sh
> this?
> Thanks a million
> --
> TS|||Hello TS,
CREATE TABLE [dbo].[Rooms] (
[RoomID] [int] NULL ,
[NumberofBeds] [int] NULL
) ON [PRIMARY]
GO
select * from Rooms
GO
RoomID NumberofBeds
-- --
200 3
201 4
202 2
select A.RoomID, B.Division
from Rooms A
Inner Join ( Select 'A' 'Division',1 'Sequence'
UNION ALL
select 'B',2
UNION ALL
select 'C',3
UNION ALL
select 'D',4
UNION ALL
select 'E',5
UNION ALL
select 'F',6 ) B
ON B.Sequence <= A.NumberofBeds
Thanks,
Gopi
"TS" <TS@.discussions.microsoft.com> wrote in message
news:07AF5AB5-BFD0-4E5D-90CE-316F267DAF4B@.microsoft.com...
>I have some Lotus Notes files that I saved as Excel spreadsheets. I
>migrated
> the files to SQL using DTS. One of the files has a table with 2 columns as
> follows:
> Room ID Number of Beds
> 201 3
> 202 2
> I need to add a column to that table that will look into the combination
> of
> each RoomID and Number Of Beds and will look like this:
> Room ID
> 201A
> 201B
> 201C
> 202A
> 202B
> So, because Room 201 has a capacity of 3 beds, it showed up as 201A, 201B
> and 201C and so forth for the other rooms. What code I can use to
> accomplish
> this?
> Thanks a million
> --
> TS|||Here is an example of creating a table with the two fields and populating th
e
standard values. Then modifying the table to add new column and updating th
e
value of that column depending on the number of rooms.
Create table #Table1
(
RoomID nvarchar (3),
NumOfBeds nvarchar (1)
)
Insert #Table1
values ('201','3')
Insert #Table1
values ('202','2')
Insert #Table1
values ('203','3')
Insert #Table1
values ('204','2')
select * from #table1
--Alter table to have GUID ID
Alter TABLE [#table1] ADD [RoomType] nvarchar (4)
GO
-- Update values for colum with conditions for number of beds
Update #Table1
Set Roomtype = RoomID+'A'
WHERE Numofbeds ='3'
Update #Table1
Set Roomtype = RoomID+'B'
WHERE Numofbeds ='2'
Select * from #Table1
Drop table #table1
Hope this helps guide you in the right direction.
"TS" wrote:

> I have some Lotus Notes files that I saved as Excel spreadsheets. I migrat
ed
> the files to SQL using DTS. One of the files has a table with 2 columns as
> follows:
> Room ID Number of Beds
> 201 3
> 202 2
> I need to add a column to that table that will look into the combination o
f
> each RoomID and Number Of Beds and will look like this:
> Room ID
> 201A
> 201B
> 201C
> 202A
> 202B
> So, because Room 201 has a capacity of 3 beds, it showed up as 201A, 201B
> and 201C and so forth for the other rooms. What code I can use to accompli
sh
> this?
> Thanks a million
> --
> TS|||Thanks a lot. Your code did exactly what I was looking for. Now the only
thing I need in order to finish the conversion is to include the description
next to the room id as follows:-
This is how the table looked like before applying your code:
Room Capacity Description
201 2 Small Single
202 1 Large Double
This is how the table looks like now after applying your code
RoomID
201A
201B
202A
What I need is to add another column to what I have now so the table will
look like this
RoomID Description
201A Small Single
201B Small Single
202A Large Double
What is the code for that.
Thank you for all your help.
TS
"Alejandro Mesa" wrote:
> Use an auxiliary numbers table.
> Example:
> use northwind
> go
> create table t1 (
> room_id int not null unique,
> number_of_beds int not null check (number_of_beds between 1 and 5)
> )
> go
> insert into t1 values(201, 3)
> insert into t1 values(202, 2)
> go
> select
> identity(int, 1, 1) as number
> into
> number
> from
> sysobjects as a
> cross join
> sysobjects as b
> go
> declare @.s varchar(255)
> set @.s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
> select
> ltrim(room_id) + substring(@.s, n.number, 1)
> from
> t1
> inner join
> number as n
> on n.number <= t1.number_of_beds
> order by
> room_id,
> n.number
> go
> drop table t1
> go
> drop table number
> go
>
> AMB
>
> "TS" wrote:
>

Friday, March 9, 2012

good matrix tutorial

Does anyone know of a good matrix tutorial which shows a finished report and how the choices for Page, Columns, Rows, and Details map to a finished report? Having a tough time wrapping my head around the direct impact, and for whatever reason, my sample data keeps triggering an "Out of memory" during preview mode.

Hello,

I don't know of any third party tutorials specifically, but have you seen the Books Online topic about Matrices?:

http://msdn2.microsoft.com/en-us/library/ms157334.aspx

Also, the AdventureWorks sample report "Company Sales" has a simple example of a matrix with nested toggleable groups on both rows and columns.

With regard to your Out of Memory error... how many rows are being returned from your DataSet?

If you have any specific questions, feel free to post them here.

-Chris

|||

I'm experiencing this out of memory error too: I have one database which I can connect to, which gives me around 300 rows, and that's fine. However, another database which returns around 6000 rows throws an out of memory exception when I try to run the report.

I'm guessing that a matrix report has to load all the data in to an internal list, and this is causing the problem. Seems a bit of a weakness to me though: for my application, most of our clients are likely to produce a large number of rows for this report, so I'll have to come up with another solution (or a different report).

Does anyone know if there is any way to change the memory available to the report? It would be nice to have an idea of how much is required, too.

good matrix tutorial

Does anyone know of a good matrix tutorial which shows a finished report and how the choices for Page, Columns, Rows, and Details map to a finished report? Having a tough time wrapping my head around the direct impact, and for whatever reason, my sample data keeps triggering an "Out of memory" during preview mode.

Hello,

I don't know of any third party tutorials specifically, but have you seen the Books Online topic about Matrices?:

http://msdn2.microsoft.com/en-us/library/ms157334.aspx

Also, the AdventureWorks sample report "Company Sales" has a simple example of a matrix with nested toggleable groups on both rows and columns.

With regard to your Out of Memory error... how many rows are being returned from your DataSet?

If you have any specific questions, feel free to post them here.

-Chris

|||

I'm experiencing this out of memory error too: I have one database which I can connect to, which gives me around 300 rows, and that's fine. However, another database which returns around 6000 rows throws an out of memory exception when I try to run the report.

I'm guessing that a matrix report has to load all the data in to an internal list, and this is causing the problem. Seems a bit of a weakness to me though: for my application, most of our clients are likely to produce a large number of rows for this report, so I'll have to come up with another solution (or a different report).

Does anyone know if there is any way to change the memory available to the report? It would be nice to have an idea of how much is required, too.

Friday, February 24, 2012

Global Search Criteria - 1 criteria for multiple columns

I am curious of other's opinions on this. It may be more a UI issue than a
database one, but there is a database side to it, and I have seen that folks
here have a broader knowledge base than just proper table structures, so...
I have an application where we need to search for an employee. You can
search on name, employee ID, or department. The determination has been made
to allow the user to enter one value, and then search for the value in any
of the above columns.
i.e.
employee_id = @.SearchString
or
employee_name like '%' + @.SearchString + '%'
or
department_name like '%' + @.SearchString + '%'
The question is, what has your experience been with this approach, from both
a database perspective, and an end user / UI perspective.One technique in such situations is to use a computed column like:
CREATE TABLE tbl (
...,
employee_id ...,
employee_name...,
department_name...
comp_col AS ( employee_id + employee_name + department_name ) );
and create an index on this comp_col column.
Now change your search pattern in your query to use comp_col LIKE '%' + @.p +
'%'. Depending on your usage you can create a covering index on all the
three columns & avoid the computed column altogether as well.
Anith|||Thanks, I'll give that approach a try to help performance.
Does anyone have any non-database related feedback on this approach?
Usability, clarity to the end user, etc?
"Anith Sen" <anith@.bizdatasolutions.com> wrote in message
news:ugqOHufdGHA.4900@.TK2MSFTNGP02.phx.gbl...
> One technique in such situations is to use a computed column like:
> CREATE TABLE tbl (
> ...,
> employee_id ...,
> employee_name...,
> department_name...
> comp_col AS ( employee_id + employee_name + department_name ) );
> and create an index on this comp_col column.
> Now change your search pattern in your query to use comp_col LIKE '%' + @.p
+
> '%'. Depending on your usage you can create a covering index on all the
> three columns & avoid the computed column altogether as well.
> --
> Anith
>|||"Anith Sen" <anith@.bizdatasolutions.com> wrote in message
news:ugqOHufdGHA.4900@.TK2MSFTNGP02.phx.gbl...
> One technique in such situations is to use a computed column like:
> CREATE TABLE tbl (
> ...,
> employee_id ...,
> employee_name...,
> department_name...
> comp_col AS ( employee_id + employee_name + department_name ) );
> and create an index on this comp_col column.
> Now change your search pattern in your query to use comp_col LIKE '%' + @.p
> + '%'. Depending on your usage you can create a covering index on all the
> three columns & avoid the computed column altogether as well.
> --
> Anith
>
Anith,
Could you explain the performance advantage to using either the computed
column or the covering index compared to just a straight where clause (e.g.
WHERE employee_id + employee_name + department_name LIKE '%' + @.p + '%' ) ?
I'm not knocking the approach, I would just like to understand. Also, it
seems as though once you use the LIKE clause, any advantage to an index
disappears.
Thanks,
Kevin|||I think I messed this one up :-( You are right, the wild card in the
beginning of the parameter will nullify the index usage.
Anith

Sunday, February 19, 2012

Global DB Search Util

I've written a small search util that displays all tables/columns that
contain the given search string.
EXEC usp_GlobalFindText 'MyText'
The problem is that EXEC(@.STR) can only return a @.@.ERROR code, I Tried:
RETURN EXEC(@.SQL) --@.SQL = SELECT COUNT(*) FROM Table WHERE ID=5
This always returns 0 because no error is thrown...@.@.ERROR = 0
Is there a more elegant way search every table/Text column?
--Billg_sd
--SOURCE CODE--
CREATE PROCEDURE dbo.usp_GetRowResult
(
@.ROWID INT,
@.VAL INT OUTPUT
)
AS
DECLARE @.SQL VARCHAR(180)
SELECT @.SQL = [Query] FROM SEARCH WHERE RowID = @.ROWID
EXEC(@.SQL)
IF @.@.ERROR <> 0
SET @.VAL = 1
ELSE
SET @.VAL = 0
RETURN
GO
CREATE PROCEDURE dbo.usp_GlobalFindText
(
@.PATTERN VARCHAR(64)
)
/* WITH ENCRYPTION */
AS
SET NOCOUNT ON
DECLARE @.ICOUNT INT
DECLARE @.TOPROWINDEX INT
DECLARE @.RETVAL INT
DECLARE @.ROWID INT
--DECLARE @.PATTERN VARCHAR(64)
--EXTRACT TEXT FIELDS TO SEARCH
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'SEARCH
')
DROP TABLE SEARCH
SELECT
IDENTITY(INT, 1, 1) AS RowID,
TABLE_NAME,
COLUMN_NAME,
QUERY = 'IF EXISTS(SELECT * FROM ' + TABLE_NAME +
' WHERE ' + COLUMN_NAME + ' LIKE ' + char(39) + '%' + @.PATTERN
+ '%' + char(39) + ') RAISERROR('''',11,1) ' ,
CAST(0 AS INT) AS TOTAL
INTO SEARCH
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE IN ('char','nvarchar','ntext','varchar', 'text')
ORDER BY TABLE_NAME, COLUMN_NAME
--SEARCH FIELDS
SELECT @.ICOUNT = MIN(ROWID) FROM SEARCH
SELECT @.TOPROWINDEX = MAX(ROWID) FROM SEARCH
WHILE @.ICOUNT <= @.TOPROWINDEX
BEGIN
SELECT @.ROWID = ROWID FROM SEARCH WHERE ROWID = @.ICOUNT
IF @.ICOUNT IS NULL
CONTINUE
EXEC usp_GetRowResult @.ROWID, @.RETVAL OUTPUT
--PRINT '@.RETVAL = ' + CAST(@.RETVAL AS VARCHAR(10))
UPDATE SEARCH
SET TOTAL = @.RETVAL
WHERE RowID = @.ROWID
SET @.ICOUNT = @.ICOUNT + 1
IF @.ICOUNT <= @.TOPROWINDEX
CONTINUE
ELSE
BREAK
END
--Display results
SELECT TABLE_NAME, COLUMN_NAME FROM SEARCH WHERE TOTAL <> 0
GOVyas has a great SP on his website
http://vyaskn.tripod.com/
"Billg_sd" <Billgsd@.discussions.microsoft.com> wrote in message
news:CDF6DF52-2341-4377-A737-7FC4CFC75E31@.microsoft.com...
> I've written a small search util that displays all tables/columns that
> contain the given search string.
> EXEC usp_GlobalFindText 'MyText'
> The problem is that EXEC(@.STR) can only return a @.@.ERROR code, I Tried:
> RETURN EXEC(@.SQL) --@.SQL = SELECT COUNT(*) FROM Table WHERE ID=5
> This always returns 0 because no error is thrown...@.@.ERROR = 0
> Is there a more elegant way search every table/Text column?
> --Billg_sd
> --SOURCE CODE--
> CREATE PROCEDURE dbo.usp_GetRowResult
> (
> @.ROWID INT,
> @.VAL INT OUTPUT
> )
> AS
> DECLARE @.SQL VARCHAR(180)
> SELECT @.SQL = [Query] FROM SEARCH WHERE RowID = @.ROWID
> EXEC(@.SQL)
> IF @.@.ERROR <> 0
> SET @.VAL = 1
> ELSE
> SET @.VAL = 0
> RETURN
> GO
> CREATE PROCEDURE dbo.usp_GlobalFindText
> (
> @.PATTERN VARCHAR(64)
> )
> /* WITH ENCRYPTION */
> AS
> SET NOCOUNT ON
> DECLARE @.ICOUNT INT
> DECLARE @.TOPROWINDEX INT
> DECLARE @.RETVAL INT
> DECLARE @.ROWID INT
> --DECLARE @.PATTERN VARCHAR(64)
> --EXTRACT TEXT FIELDS TO SEARCH
> IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME =
'SEARCH')
> DROP TABLE SEARCH
> SELECT
> IDENTITY(INT, 1, 1) AS RowID,
> TABLE_NAME,
> COLUMN_NAME,
> QUERY = 'IF EXISTS(SELECT * FROM ' + TABLE_NAME +
> ' WHERE ' + COLUMN_NAME + ' LIKE ' + char(39) + '%' + @.PATTERN
> + '%' + char(39) + ') RAISERROR('''',11,1) ' ,
> CAST(0 AS INT) AS TOTAL
> INTO SEARCH
> FROM INFORMATION_SCHEMA.COLUMNS
> WHERE DATA_TYPE IN ('char','nvarchar','ntext','varchar', 'text')
> ORDER BY TABLE_NAME, COLUMN_NAME
> --SEARCH FIELDS
> SELECT @.ICOUNT = MIN(ROWID) FROM SEARCH
> SELECT @.TOPROWINDEX = MAX(ROWID) FROM SEARCH
> WHILE @.ICOUNT <= @.TOPROWINDEX
> BEGIN
> SELECT @.ROWID = ROWID FROM SEARCH WHERE ROWID = @.ICOUNT
> IF @.ICOUNT IS NULL
> CONTINUE
> EXEC usp_GetRowResult @.ROWID, @.RETVAL OUTPUT
> --PRINT '@.RETVAL = ' + CAST(@.RETVAL AS VARCHAR(10))
> UPDATE SEARCH
> SET TOTAL = @.RETVAL
> WHERE RowID = @.ROWID
> SET @.ICOUNT = @.ICOUNT + 1
> IF @.ICOUNT <= @.TOPROWINDEX
> CONTINUE
> ELSE
> BREAK
> END
> --Display results
> SELECT TABLE_NAME, COLUMN_NAME FROM SEARCH WHERE TOTAL <> 0
> GO
>
>|||This website is huge. Where can I find this sample?
"Uri Dimant" wrote:

> Vyas has a great SP on his website
> http://vyaskn.tripod.com/
>

Giving user permissions tp columns

Hi
I have created a user and given select permissions on a table, I want to go deeper and just give select on a few columns within the table but unable to do so. Can someone tell me how I can do this.
ThanksRevoke the SELECT right for that table from the user.
Create a view that contains only the columns he/she should see
Grant the user SELECT on that view.

P.S.: what do you mean with "tp columns"? Is tp your abbreviation for table?|||Thanks for that.

It was meant to say to it was a typo.

Thanks Shammat|||Do you know what Books Online is?

From BOL:

GRANT
{ ALL [ PRIVILEGES ] | permission [ ,...n ] }
{
[ ( column [ ,...n ] ) ] ON { table | view }
| ON { table | view } [ ( column [ ,...n ] ) ]
| ON { stored_procedure | extended_procedure }
| ON { user_defined_function }
}
TO security_account [ ,...n ]
[ WITH GRANT OPTION ]
[ AS { group | role } ]|||Yes I do but I forgot it was there.