sp_setapprole in SQL server 2008 - sql-server-2008

I want to insert a value to a table in the database using a set of parameters, for which I want to make use of sp_setapprole. I know this sp can be used to set some permissions.
I am not aware how to even start.
My table: XYZ
Parameters: ViewerID, AppID, Key
I want to output Cookie and I want to query the table to delete/update and read a the parameter from another parameter.

check with the below query
DECLARE #cookie varbinary(8000);
EXEC sp_setapprole 'Sales11', 'fdsd896#gfdbfdkjgh700mM'
, #fCreateCookie = true, #cookie = #cookie OUTPUT;
-- The application role is now active.
SELECT USER_NAME();
-- This will return the name of the application role, Sales11.
EXEC sp_unsetapprole #cookie;
-- The application role is no longer active.
-- The original context has now been restored.
GO
SELECT USER_NAME();
-- This will return the name of the original user.
GO

Related

Attempt to fetch logical page in database 2 failed. It belongs to allocation unit X not to Y

Started to get following error when executing certain SP. Code related to this error is pretty simple, joining #temp table to real table
Full text of error:
Msg 605, Level 21, State 3, Procedure spSSRSRPTIncorrectRevenue, Line 123
Attempt to fetch logical page (1:558552) in database 2 failed. It belongs to allocation unit 2089673263876079616 not to 4179358581172469760.
Here is what I found:
https://support.microsoft.com/en-us/kb/2015739
This suggests some kind of issue with database. I run DBCC CHECKDB on user database and on temp database - all passes.
Second thing I'm doing - trying to find which table those allocation units belong
SELECT au.allocation_unit_id, OBJECT_NAME(p.object_id) AS table_name, fg.name AS filegroup_name,
au.type_desc AS allocation_type, au.data_pages, partition_number
FROM sys.allocation_units AS au
JOIN sys.partitions AS p ON au.container_id = p.partition_id
JOIN sys.filegroups AS fg ON fg.data_space_id = au.data_space_id
WHERE au.allocation_unit_id in(2089673263876079616, 4179358581172469760)
ORDER BY au.allocation_unit_id
This returns 2 objects in tempdb, not in user db. So, it makes me think it's some kind of data corruption in tempdb? I'm developer, not DBA. Any suggestions on what I should check next?
Also, when I run query above, how can I tell REAL object name that I understand? Like #myTempTable______... instead of #07C650CE
I was able to resolve this by clearing the SQL caches:
DBCC FREEPROCCACHE
GO
DBCC DROPCLEANBUFFERS
GO
Apparently restarting the SQL service would have had the same affect.
(via Made By SQL, reproduced here to help others!)
I have like your get errors too.
firstly you must backing up to table or object for dont panic more after. I tryed below steps on my Database.
step 1:
Backing up table (data movement to other table as manuel or vs..how can you do)
I used to below codes to my table move other table
--CODE-
set nocount on;
DECLARE #Counter INT = 1;
DECLARE #LastRecord INT = 10000000; --your table_count
WHILE #Counter < #LastRecord
BEGIN
BEGIN TRY
BEGIN
insert into your_table_new SELECT * FROM your_table WHERE your_column= #Counter --dont forget! create your_table_new before
END
END TRY
BEGIN CATCH
BEGIN
insert into error_code select #Counter,'error_number' --dont forget the create error_code table before.
END
END CATCH
SET #Counter += 1;
END;
step 2:
-DBCC CHECKTABLE(your_table , REPAIR_REBUILD )
GO
check your table. if you have an error go to other step_3.
step 3:
!!attention!! you can lost some data/datas on your table. but dont worry. so you backed-up your table in step_1.
-DBCC CHECKTABLE(your_table , REPAIR_ALLOW_DATA_LOSS)
GO
Good luck!
~~pektas
In my case, truncating and re-populating data in the concerned tables was the solution.
Most probably the data inside tables was corrupted.
Database ID 2 means your tempdb is corrupted. Fixing tempdp is easy. Restart sqlserver service and you are good to go.
This could be an instance of a bug Microsoft fixed on SQL Server 2008 with queries on temporary tables that self reference (for example we have experienced it when loading data from a real table to a temporary table while filtering any rows we already have populated in the temp table in a previous step).
It seems that it only happens on temporary tables with no identity/primary key, so a workaround is to add one, although if you patch CU3 or later you also can enable the hotfix via turning a trace flag on.
For more details on the bug/fixes: https://support.microsoft.com/en-us/help/960770/fix-you-receive-error-605-and-error-824-when-you-run-a-query-that-inse

Getting sliced data between two timeskip database transfer data

How can I get 'sliced' data and remove the data from database?
I was using two database MySQL and SQL SERVER.
Example:
Yesterday I transfered data from MySql to Sql Server about 1000 rows,
then today I simply deleted 5 rows in MySql then did the transfer again.
So, how can I know which ID was deleted from MySQL then remove it in SQL Server?
I was transferring data using Stored Procedures that check every ID in every loop inserting.
foreach($data AS $key => $value){ $this->MsSQL->Exec('exec sp_pendaftar {ID} {NAME}'); }
I have stored procedure like this:
CREATE PROCEDURE [dbo].[sp_pendaftar] #id INT,#name varchar(45) AS DECLARE #id nvarchar(40); SET NOCOUNT ON; SET #id = (SELECT TOP 1 id FROM t_pendaftar WHERE id = #id);
IF #id IS NULL BEGIN
INSERT INTO t_pendaftar VALUES(#id,#name);
END;
ELSE
BEGIN
UPDATE t_pendaftar SET name = #name WHERE id = #id;
END;
GO
Please help.
I do not understand anything of the SQL-Server code, but I would suggest to make a part of the replication via application. So, for the bigger and more dynamical data tables you could define a delete_pendafter and a insert_pendafer table (and also a change_pendafter if needed).
Before you delete from t_pendafter, you select just those rows into delete_pendafter. This is even possible with triggers, if that does not slow down the application too much.
On SQL-Server-side I hope you have a delete-join, so you just remove the deleted rows. In MySQL this would look like
DELETE orig
FROM t_pendafter AS orig
INNER JOIN delete_pendafter AS del ON del.id = orig.id
This solution can be extended to INSERT and CHANGE, but must be done with some care.
Every now and then you should make a full copy, and you should write some checks to ensure the data is consistent.
Just got some answer from my partner.
First, grab array id from MySQL DB and then grab array id from SQL Server and compare which id that not present in SQL Server using array_diff().
$MySQL : array[id] => [11,12,13,15,16,19,25]
$SQL_Server : array[id] => [11,12,13,14,15,16,17,18,19,20,21,23,24,25 ]
$array_to_be_deleted : array($SQL_Server , $MySQL)
print_r($array_to_be_deleted);
result would be:
array => [14,17,18,20,21,23,24]
Hope anyone can try to correct me.

Reporting parameter saving

In SSRS, User wants his report parameters selection should be remembered.That is for the first time user will select parameters and somehow next time onward it should remember parameters.
Is it possible to achieve this in any way?? Anybody has any thought on this?
The My Reports feature allows users to build and save their own reports on the server. It also allows them to create linked reports that have parameter defaults set up the way they want. That's the only built-in feature that might get you what you want. It is pretty limited, though, to be honest.
On the other hand, you could build a user parameter storage feature of your own. Here's a rudimentary example.
Start with a table to store your user report parameter values.
create table UserReportParameters (
UserName nvarchar(50),
ParameterSet nvarchar(50),
ParameterName nvarchar(50),
ParameterValue nvarchar(max)
)
Since you're seeking a way to store a user's parameter values, I'll assume you're using some sort of authentication on your reporting service, such as Windows Authentication. We'll be storing the UserName provided by that authentication service along with an arbitrarily named ParameterSet. This ParameterSet value could be the url to the report or some other unique identifier for the report or perhaps a logical name for a set of reports that all use common parameters such as "Sales Reports".
We'll need a way to save these parameter values. A simple stored procedure will do the trick.
create proc SaveUserReportParameter (
#UserName nvarchar(50),
#ParameterSet nvarchar(50),
#ParameterName nvarchar(50),
#ParameterValue nvarchar(max)
)
as
delete UserReportParameters where UserName = #UserName and ParameterSet = #ParameterSet and ParameterName = #ParameterName
insert UserReportParameters select #UserName, #ParameterSet, #ParameterName, #ParameterValue
Now in your report's main dataset query or stored procedure (somewhere you can be sure the code runs once per report execution) you just need to call that stored procedure to store each value.
exec SaveUserReportParameter #UserName, 'Sales Reports', 'StartDate', #StartDate
exec SaveUserReportParameter #UserName, 'Sales Reports', 'EndDate', #EndDate
exec SaveUserReportParameter #UserName, 'Sales Reports', 'DepartmentId', #DepartmentId
exec SaveUserReportParameter #UserName, 'Sales Reports', 'PromoCode', #PromoCode
Note that the table stores everything as nvarchar. I'm being lazy here and letting implicit conversion happen. If you want to store values such as datetime in a specific format, you'll need to convert them when inserting them into the table variable. The #UserName report parameter used here and below should be an internal parameter whose default value is =User!UserId.
Now that we're storing parameters, let's start using them. We'll need another stored procedure. This one's a bit bigger.
create proc GetUserReportParameters (
#UserName nvarchar(50),
#ParameterSet nvarchar(50),
#Columns nvarchar(max)
) as
declare #sql nvarchar(max)
set #sql = '
select * from
(
select
p.ParameterName,
p.ParameterValue
from
(select #UserName UserName, #ParameterSet ParameterSet) stub
left join UserReportParameters p on p.UserName = stub.UserName and p.ParameterSet = stub.ParameterSet
) v
pivot (
min(ParameterValue)
for ParameterName in (' + #Columns + ')
) as pvt'
exec sp_executesql #sql, N'#UserName nvarchar(50), #ParameterSet nvarchar(50)', #UserName, #ParameterSet
And then to call it
exec GetUserReportParameters #UserName, 'Sales Reports', 'StartDate,EndDate,DepartmentId,PromoCode'
As you can see, you provide the UserName and ParameterSet values. The same as you used when you called the save procedure. Here, though, you're also providing a string that's a simple comma separated list of column names. These column names are used by a pivot query to ensure your result set includes columns by those names. You should be aware those columns can and will contain nulls, especially when a user first accesses the report. You should also be aware that all values are nvarchar(max). If you need to parse or convert any values or provide your own defaults when the value is null, you'll need to do some extra work.
In an embedded dataset named UserReportParameters I call the procedure, store the values locally and then do my conversions and null-swapping as necessary.
declare #Parameters table (
StartDate datetime,
EndDate datetime,
DepartmentId int,
PromoCode nvarchar(50)
)
insert #Parameters
exec GetUserReportParameters #UserName, 'Sales Reports', 'StartDate,EndDate,DepartmentId,PromoCode'
select
isnull(cast(StartDate as datetime), dateadd(day,datediff(day,0,getdate()),0)) StartDate,
isnull(cast(EndDate as datetime), dateadd(day,datediff(day,0,getdate()),0)) EndDate,
isnull(cast(DepartmentId as int),15) DepartmentId,
isnull(PromoCode,'FAKESALE') PromoCode
from #Parameters
Now, every time you run the report (more specifically, every time the dataset that contains your call to the save procedure is executed) the parameters you opt to save will be saved. When you leave and come back to the report page, the parameters will be populated with the last values you chose. Note that you don't have to save every parameter value. Just the ones you want to save per-user. You also don't have to use every parameter value that's saved in a given ParameterSet. If you have two sales reports, one that uses PromoCode and one that uses ProductCategory you can save both their parameter values in the 'Sales Reports' parameter set without worry that they'll interfere with one another. Additionally, you could easily create two separate datasets in your report, each pulling a different parameter set. For instance, if PromoCode actually gets saved in the 'Marketing' parameter set and DepartmentId is from the Products parameter set. Once you have this framework, you have a lot of flexibility in how your user parameter defaults get saved.
It is generally considered bad practice to allow reports to alter data. I agree with this conventional wisdom when it comes to domain data. However, this parameter-saving feature is really more of an extension of SSRS functionality, akin to report execution logging. I do not believe it violates the principle.
SCALABILITY -- This will work great for a small number of reports for a relatively small number of users. There could easily be performance issues in larger enterprise environments. (That's why I called this a "rudimentary example" at the start.) You could address this by redesigning the value storage mechanism. For instance, use pre-defined tables for each parameter set instead of dumping them all into a single table so you can avoid pivoting. I'll leave that decision and work to you.
Try this one. It's a bit long, I will just attach the document link here.
Report Parameter Saving Solution

T-SQL Change Data Capture log cleanup

I have enabled CDC on few tables in my SQL server 2008 database. I want to change the number of days I can keep the change history.
I have read that by default change logs are kept for 3 days, before they are deleted by sys.sp_cdc_cleanup_change_table stored proc.
Does anyone know how I can change this default value, so that I can keep the logs for longer.
Thanks
You need to update the cdc_jobs.retention field for your database. The record in the cdc_jobs table won't exist until at least one table has been enabled for CDC.
-- modify msdb.dbo.cdc_jobs.retention value (in minutes) to be the length of time to keep change-tracked data
update
j
set
[retention] = 3679200 -- 7 years
from
sys.databases d
inner join
msdb.dbo.cdc_jobs j
on j.database_id = d.database_id
and j.job_type = 'cleanup'
and d.name = '<Database Name, sysname, DatabaseName>';
Replace <Database Name, sysname, DatabaseName> with your database name.
Two alternative solutions:
Drop the cleanup job:
EXEC sys.sp_cdc_drop_job #job_type = N'cleanup';
Change the job via sp:
EXEC sys.sp_cdc_change_job
#job_type = N'cleanup',
#retention = 2880;
Retention time in minutes, max 52494800 (100 years). But if you drop the job, data is never cleaned up, the job isn't even looking, if there is data to clean up. In case of wanting to keep data indefinitely, I'd prefer dropping the job.

Unable to retrieve column information: No colum information was returned by the sql command

I am using Microsoft sql server 2008, I tried all the 3 solutions, but every time I get the same error
Error at Data Flow Task[OLEDB source[449]]:No colum information was returned by the sql command
I am using the following batch of sql statments to retrieve the server level configuration of all servers in my company. The table variable #tb1_SvrStng has 83 columns and it is populated using different resources.
So I summarize the sql script. I cannot use it as stored procedure because this script is going to run against 14 servers (once for each server). So if I store the procedure on one server, other server cannot execute that procedure in its context.
I will highly appreciate your help. I am not using any temporary table in my script.
declare #tb1_SvrStng table
(
srvProp_MachineName varchar(50),
srvProp_BldClrVer varchar(50),
srvProp_Collation varchar(50),
srvProp_CNPNB varchar(100),
...
xpmsver_ProdVer varchar(50),
..... .
syscnfg_UsrCon_cnfgVal int,
.....
);
insert into #tb1_SvrStng
(
srvProp_BldClrVer,
srvProp_Collation,
srvProp_CNPNB , ........
........ .
)
select convert(varchar, serverproperty('BuildClrVer')),
convert(varchar, serverproperty('Collation'))
........
.......
declare #temp_msver1 table
(
id int, name varchar(100),
...........
);
insert into #temp_msver1 exec xp_msver
Update #tb1_SvrStng
set xpmsver_ProdVer =
(
select value from #temp_msver1 where name = 'ProductVersion'
),
xpmsver_Platform =
(
select value from #temp_msver1 where name = 'Platform'
),
.....
......
select
srvProp_SerName as srvProp_SerName,
getdate() as reportDateTime,
srvProp_BldClrVer as srvProp_BldClrVer,
srvProp_Collation as srvProp_Collation,
.....
.....
from #tb1_SvrStng
From what i can gather from your code and question is that the query cannot be processed outside runtime, because you're doing something dynamic to it, or that it won't process it since it's doing something funky.
One trick to this would be to use the Source component in the data flow task to something "dummy" - which you can fake with a query like this
SELECT
CONVERT(DATATYPE,NULL) AS srvProp_SerName,
CONVERT(DATETIME,NULL) AS reportDateTime,
CONVERT(DATATYPE,NULL) AS srvProp_BldClrVer,
CONVERT(DATATYPE,NULL) AS srvProp_Collation
This way the source component should be able to read the metadata. You can then put your proper query (as long as it's within the limits of the length of the query text) into a variable, and then assign this as an expression to the source component.
At runtime it will then use the expression query - and hopefully don't mind too much the metadata issue.
This may or may not work but it should be worth a try since it won't take long to confirm.