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

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.

Related

How to use the same SSIS Data Flow with different Date Values?

I have a very straightforward SSIS package containing one data flow which is comprised of an OLEDB source and a flat file destination. The OLEDB source calls a query that takes 2 sets of parameters. I've mapped the parameters to Date/Time variables.
I would like to know how best to pass 4 different sets of dates to the variables and use those values in my query?
I've experimented with the For Each Loop Container using an item enumerator. However, that does not seem to work and the package throws a System.IO.IOException error.
My container is configured as follows:
Note that both variables are of the Date/Time data type.
How can I pass 4 separate value sets to the same variables and use each variable pair to run my data flow?
Setup
I created a table and populated it with contiguous data for your sample set
DROP TABLE IF EXISTS dbo.SO_67439692;
CREATE TABLE dbo.SO_67439692
(
SurrogateKey int IDENTITY(1,1) NOT NULL
, ActionDate date
);
INSERT INTO
dbo.SO_67439692
(
ActionDate
)
SELECT
TOP (DATEDIFF(DAY, '2017-12-31', '2021-04-30'))
DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)), '2017-12-31') AS ActionDate
FROM
sys.all_columns AS AC;
In my SSIS Package, I added two Variables, startDate and endDAte2018 both of type Date Time. I added an OLE DB Connection manager pointed to the database where I made the above tables.
I added a Foreach Item Enumerator, configured it for Item Enumerator and defined the columns there as datetime as well
I populated it (what a clunky editor) with the year ranges from 2018 to 2020 as shown and 2021-01-01 to 2021-04-30.
I wired the variables up as shown in the problem definition and ran it as is. No IO error reported.
Once I knew my foreach container was working, the data flow was trivial.
I added a data flow inside the foreach loop with an OLE DB Source using a parameterized query like so
DECLARE #StartDate date, #EndDate date;
SELECT #StartDate = ?, #EndDate = ?;
SELECT *
FROM
dbo.SO_67439692 AS S
WHERE
S.ActionDate >= #StartDate AND S.ActionDate <= #EndDate;
I mapped my two variables in as parameter names of 0 and 1 and ran it.
The setup you described works great. Either there is more to your problem than stated or there's something else misaligned. Follow along with my repro and compare it to what you've built and you should see where things are "off"

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

sp_setapprole in 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

Parameters in SQL Server 2008

I have a stored procedure that pulls data for a report. I'm having a problem with the parameters. I have a couple temp tables and some joins that work so I have omitted them below. The problem is this line:
WHERE
SeminarDivision = #SeminarDivision AND SeminarType = #SeminarType
When I put this where clause in to use my seminar parameters the stored proc returns nothing But I need to generate a report based on those two parameters. So where do the parameters go? Can anyone help?
#StartDate DateTime,
#EndDate DateTime,
#SeminarDivision VARCHAR(50),
#SeminarType VARCHAR(50)
)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
... OMITTED
SELECT
WL.PID,
CONVERT(varchar(20), upper(substring(FirstName,1,1))+
LOWER(substring(FirstName,2,19))) AS FirstName,
CONVERT(varchar(20), upper(substring(LastName,1,1))+
LOWER(substring(LastName,2,19))) AS LastName,
S.SeminarDivision,
S.SeminarType,
S.StartDate,
S.SeminarLocation
FROM
#tblWaitList WL
INNER JOIN #tblSeminar S ON WL.SeminarGuid=S.SeminarGuid
WHERE
SeminarDivision = #SeminarDivision AND SeminarType = #SeminarType
ORDER BY
LastName,FirstName,StartDate
First and foremost there is nothing wrong with your code, when asking where do these parameters go, they go exactly where you put them. The question is - is the data coming in for SeminarDivision and SeminarType the right type of data? For instance just as a test,
copy the code into a new sql code query inside the editor. Run the command without the where, if you get values great. Now change the where to
WHERE
SeminarDivision = "Possible_Value"
Where Possible_Value should be a possible value...If it returns rows, good...now add the second condition also hardcoding a value:
WHERE SeminarDivision = "Possble_Value" AND SeminarType="Possible_Value_2"
Getting any data? Is it possible you want OR rather then AND ?
There's nothing wrong with the 'location' of your params.
If you're getting no data back, it's either because you've not populated #tblWaiList or #tblSeminar or because the records simply don't match your WHERE clause.
Check your params have the value you think they do by executing print #SeminarDivision etc.
SELECT * FROM #tblSeminar may give you a clue too.
You are not setting parameters correctly for the call.
Try this in SSMS, change values accordingly
EXEC Proc '20110101', '20111101', 'PossibleDivision', 'PossibleType'
If this fails, then show us "OMITTED" code
if this works, show us how you are calling this from the client code