Create delimited string from a row in stored procedure with unknown number of elements - sql

Using SQL Server 2000 and Microsoft SQL Server MS is there a way to create a delimited string based upon an unknown number of columns per row?
I'm pulling one row at a time from different tables and am going to store them in a column in another table.

A simple SQL query can't do anything like that. You need to specify the fields you are concatenating.
The only method that I'm aware of is to dynamincally build a query for each table.
I don't recall the structure of MSSQL2000, so I won't try to give an exact example, maybe someone else can. But there -are- system tables that contain table defintions. By parsing the contents of those system tables you can dynamically build the necessary query for each source data table.
TSQLthat writes TSQL, however, can be a bit tricky to debug and maintain :) So be careful how you structure everything...
Dems.
EDIT:
Or just do it in your client application.

Related

Using SSMA to convert from Access to SQL, scripting the fixes

I am using SSMA to convert from an Access db to a SQL 2019 DB.
There are some things I need to fix in the access DB so I am trying to figure out whether or not these things can be done via a query in access or you have to use the goofy UI and do everything manually.
So I had a couple of questions about queries in Microsoft Access:
Can you modify the 'required' attribute on a column within a table by using a query?
Can you configure Index (dupes) on a column by using a query?
Can you change validation rules using a query?
Can you create/delete relationships using a query?
Can you change the field length of a column by using a query?
Any examples of any of these would be helpful, when I google for ms access related things all of the content is either related to Access 2007/2010 or its very UI heavy rather than Query heavy.
I am trying to script this because I may have to do this migration several times.
Update: I was able to get most of what i needed figured out..
ALTER TABLE Users ALTER COLUMN Type CHECK(In ("I","U","") Or Is Null);
Still havent found a way to change the 'ValidationRule'.. trying to change it to
In ("I","U","") Or Is Null
Look into the Data Definition Language section of the MS Access SQL Reference, specifically the ALTER TABLE statement, which will cover the majority of your questions.
For example, in response to:
Can you change the field length of a column by using a query?
ALTER TABLE Table1 ALTER COLUMN Field1 TEXT(100)
The above will change the data type of the field Field1 within table Table1 to a text field accommodating 100 characters.

Use SQL Field in SSIS Variable

Is it possible to reference a SQL field in your SSIS variable?
For instance, I would like use the field from the "table" below
Select '999999' AS Physician_Profile_ID
as a dynamic variable (named "CMSPhysProID" in our example) here
I plan on concatenating multiple IDs into a In statement.
Possible by using execute sql taskIn left side pan of Execute SQL task, general tab 1.Select result set as single row2. Connection type ole db 3. Set connection and form SQL statement, As you mentioned Select '999999' AS Physician_Profile_ID 4.Go to result set in your left side pan 5. Add your variable where you want to store '999999' 6. Click ok
If you are looking to store the value within the variable to be used later, you can simply use an Execute SQL Task with a single row result set. More details in the following article:
SSIS Basics: Using the Execute SQL Task to Generate Result Sets
If you are looking to add a computed column while importing data, you must use a Derived Column Transformation within the data flow task to add a column based on another one, you can refer to the following article for more details about this component:
SSIS Derived Columns with Multiple Expressions vs Multiple Transformations
What are you trying to accomplish by concatenating the IDs into an "IN" statement? If the idea is to use the values of the IDs to limit the results, as a dynamic WHERE clause, you may have better luck just using a lookup against either a table you maintain with the desired IDs or even a static list generated in the package with a script task. (If you can use the lookup table method it will be much easier to maintain as you only have to update a table, not your source code.)
Alternatively, you may even be able to accomplish the goal with a join. Create a temp table from the profile IDs you want to keep and join to it, or, again, use it as a lookup component. Dynamically creating a where clause using IN will come in a lot slower and will be cumbersome to maintain.

SSIS - fill unmapped columns in table in OLE DB Destination

As you can see in the image below, I have a table in SQL Server that I am filling via a flat file source. There are two columns in the destination table that I want to update based on the logic listed below:
SessionID - all rows from the first CSV import will have a value of 1; the second import will have a value of 2, and so on.
TimeCreated - datetime value of when the CSV imports happened.
I don't need help with how to write the TSQL code to get this done. Instead, I would like someone to suggest a method to implement this as a Data Flow task within SSIS.
Thank you in advance for your thoughts.
Edit 11/29/2012
Since all answers so far suggested taking care of this on the SQL Server side, I wanted to show you what I had initially tried doing (see image below), but it did not work. The trigger did not fire in SQL Server after SSIS inserted the data into the destination table.
If any of you can explain why the trigger did not fire, that would be great.
If you are able to modify the destination table, you could make the default values for SessionID and TimeCreated do all the work for you. SessionID would be an auto-incremental integer while the default value for TimeCreated would be getdate() or gettime() depending on the data type.
Now, if you truly need it the values to be created as part of your workflow, you can use variables for each.
SessionID would be a package variable which is set by an Execute SQL Task. Just reference the variable in your result set and have your SQL determine the next number to use. There are potential concurrency issues with this, though.
TimeCreated is easily done by creating a Derived Column in your data flow based on the system variable StartTime.
You can use a Derived Column to fill the TimeCreated column, if you want the time of the data flow to happen, you just use the date and time function to get the current datetime. If you want a common timestamp for the whole package (all files) you can use the system variable #[System::StartTime] (or whatitwascalled).
For the CSV looping (i guess), you use a foreach loop container, and map an iterative value to a user variable that you map in the derived column for SessionID as mentioned above.
First, I'd better do it on SQL Server side :)
But if you don't want or cannot to do it on server side you can use this approach:
It is obvious that you need to store SessionID somewhere you can create a txt file for that or better some settings table in SQL Server or there can be other approaches.
To add columns SessionID and TimeCreated to OLE Destination you can use Derived columns

Dynamically generated SQL security concerns (sql injection etc.)

We are in the process of developing an "API" for one of our products. This will allow the user to define which columns they wan't to return from their "queries" and we will build the needed SQL.
I know that you should always use parameterized queries to avoid SQL injection attacks. However is there any security risks when building a statement where the columns returned are defined by the users? Lets say we have the following api request. This is just an example to illustrate what I mean :)
/api/customers/getall?fields=Name,Phone,Email&where=Zip=1000
The SQL will be
SELECT Name, Phone, Email FROM Customers WHERE Zip = #Zip
I'm not thinking about just taking the fields parameter and building the SQL directly around that, it will probably be made into a list and returned with some default columns like Id and Modified.
What should you be aware of in this situation? And how would you protect against attacks?
-- Christian
Create a Stored Procedure
This will let you check the input Stings and you should be on the safe side.
See:
MSDN Create Stored Procedures
First, I do a query to get the fields of the selected table(s) from the INFORMATION_SCHEMA.COLUMNS metadata table.
Querying database metadata
The column names pulled from the database are safe to use. Then I compared the fields in the SELECT clause with the "safe fields list". If one of the selected fields isn't on the clean list, then remove it or don't run the generated SQL at all.

Using SQL Stored Procedure as data for a Microsoft Dynamics CRM report

We need to have a semi complex report in CRM that displays some accumulated lead values. The only way I see this report working is writing a stored procedure that creates a couple of temporary tables and calculates/accumulates data utilizing cursors. Then is the issue of getting the data from the stored procedure to be accessible from the Reporting Server report. Does anyone know if that's possible? If I could have the option of writing a custom SQL statement to generate report data, that would be just excellent.
Any pointers ?
Edit:
To clarify my use of cursors I can explain exactly what I'm doing with them.
The basis for my report (which should be a chart btw) is a table (table1) that has 3 relevant columns:
Start date
Number of months
Value
I create a temp table (temp1) that contains the following columns:
Year
Month number
Month name
Value
First I loop through the rows in the first table and insert a row in the temptable for each month, incrementing month, while setting the value to the total value divided by months. I.e:
2009-03-01,4,1000 in table1 yields
2009,03,March,250
2009,04,April,250
2009,05,May,250
2009,06,June,250
in the temp1 table.
A new cursor is then used to sum and create a running total from the values in temp1 and feed that into temp2 which is returned to the caller as data to chart.
example temp1 data:
2009,03,March,250
2009,04,April,200
2009,04,April,250
2009,05,May,250
2009,05,May,100
2009,06,June,250
yields temp2 data:
2009,03,March,250,250
2009,04,April,450,700
2009,05,May,350,1050
2009,06,June,250,1300
Last column is the running totals, which starts at zero for each new year.
Have you considered using views. Use a heirarchy of views if it is very complicated. Each view would represent one of your temporary tables.
EDIT Based on comments
I was thinking of SQL views, basically the same SQL as you would have written in your stored procedures.
I haven't done this - just thinking how I would start. I would make sure when the stored procedures populate the temporary tables they use the Filtered views for pulling data. I would then set the access to execute the SP to have the same security roles as the Filtered views (which should be pretty much to allow members of the PrivReportingGroup).
I would think that would cover allowing you to execute the SP in your report. I imagine if you set up the SP before hand, the SSRS designer has some means of showing you what data is available and to select an SP at design time. But I don't know that for sure.
First, since most cursors are unneeded, what exactly are you doing in them. Perhaps there is a set-based solution and then you can use a view.
Another possible line of thought, if you are doing something like running totals in the cursor, is can you create a view as the source without the running total and have the report itself do that kind of calculation?
Additionally, SSRS reports can use stored procs as a data source, read about how in Books online.
I found the solution. Downloaded Report Builder 2.0 from Microsoft. This allows me to write querys and call stored procedures for the report data.
Microsoft SQL Server Report Builder link