Showing posts with label write. Show all posts
Showing posts with label write. Show all posts

Tuesday, March 27, 2012

Easy SQL Server Version Identification

I know about @.@.version and SERVERPROPERTY, but I am looking for a query that will determine between SQL Server 2000 and 2005. I need to write an if/then statement and don't want to have to add all of the 9.xxx.xx versions for 2005 and keep that updated with each hotfix that comes out.
-Kyle

Use the following query..

Tested in all the versions..

Code Snippet

Declare @.version as Varchar(10);

Set @.version = Cast(serverproperty('ProductVersion') as Varchar)

if charindex('10.',@.version) = 1

Print 'It is SQL Server 2008'

if charindex('9.',@.version) =1

Print 'It is SQL Server 2005'

if charindex('8.',@.version) =1

Print 'It is SQL Server 2000'

|||The final query looked like this...thanks for your help.

IF CONVERT(char(1),SERVERPROPERTY('ProductVersion'))>='9' --pre SQL 2005
BEGIN
DECLARE @.Server [nchar] (100)
SET @.Server = (CONVERT(char(100), (SELECT SERVERPROPERTY('Servername'))))

INSERT INTO [tempdb].[dbo].[User_Auditing] (Server, UserName, WinAuth, SQL_Auth_UserName, PassPolicyOn)
SELECT @.Server, s.name, isntuser, q.name, is_policy_checked
FROM sys.syslogins s FULL OUTER JOIN sys.sql_logins q
ON (s.name = q.name)
END

-Kyle

Monday, March 26, 2012

Easy query help... :(

Hi,

I'm trying to write a sql query to create a report that will act kind of like a Mail Merge in Microsoft Word. I want to send letters to our customers to remind them their machines need to be ballbar'd or calibrated.

My database is set up as follows:

CustomerInformation(CustomerID[pk], CompanyName, CompanyPhone, etc etc etc)

CustomerMachine(MachineID[pk], MachineManufacturer, MachineModel, MachineSerialNumber, MachineSize, CustomerID[fk])

LaserCalibrations(LaserID[pk], LaserDate, MachineID[fk])

Ballbars(BallbarID[pk], BallbarDate, MachineID[fk])

My query looks like this:

SELECT CustomerInformation.CustomerID, CustomerMachine.CustomerID, CustomerMachine.MachineID, CustomerMachine.MachineManufacturer, CustomerMachine.MachineModel, CustomerMachine.MachineSerialNumber, CustomerMachine.MachineSize, LaserCalibrations.LaserID, LaserCalibrations.LaserDate, LaserCalibrations.MachineID

FROM CustomerInformation, CustomerMachine, LaserCalibrations

WHERE (((CustomerInformation.CustomerID)=CustomerMachine .CustomerID) And ((CustomerMachine.MachineID)=LaserCalibrations.Mac hineID))
ORDER BY CustomerInformation.CompanyName, LaserCalibrations.LaserDate;

The problem is that it will not print the laser calibration dates in order. I wanted to include a history of past service on the letter. I tried to write the query including ballbars, but it got too messy, I think I was missing a "Distinct" descripter. I also want to change the price according to the size of the machine... and I'm not certain how to go about doing that.

Please help :)

Thanks!you have here two unrelated one-to-many relationships that cannot easily be combined in one query

if a single machine has 3 LaserCalibrations and 4 Ballbars, the query will return 12 rows for that machine

you need two separate queries, one for LaserCalibrations and a separate one for Ballbars

Thursday, March 22, 2012

Easy IF statement (Beginner)

Im not really keen on If statements, so im trying to figure out how to write an if statement in a matrix. I want it to list the values that begin with 4's as 2004 the values that start with 5's as 2005 and the values that begin with 6's as 2006. How do i do this? Whats the IF statement code, i know how to put one option. but now all.

=IIF(Fields!ICNNo.Value=Left(1),2004,) ? I know thats wrong..

Please Help.

One way you could do this is using nested IIF statements. Like this:

=iif(left(Fields!ICNNo.Value, 1) = "4", "2004",
iif(left(Fields!ICNNo.Value, 1) = "5", "2005",
iif(left(Fields!ICNNo.Value, 1) = "6", "2006", "OtherValue")))

Hope this helps.

Jarret

|||It worked!!! THANKS ALOT!!!! It worked perfectly!

Monday, March 19, 2012

Dynamically pick the source and destination tables

I want to write a SSIS which picks up the source and destination tables at runtime is it possible. As we have a SSIS which is used to pull data from oracle but the source and destination table name changes.

If the metadata changes (that is the column names change and/or data types) then you cannot do this without manually accounting for the differences.

If the structures are the same, then you can build SQL statements to select against the appropriate table name. You can build the SQL in a variable expression.|||

Would you please give an example for this.

|||A little bit of searching will help you out...

I found: http://blogs.conchango.com/jamiethomson/archive/2005/12/09/2480.aspx|||

All the source tables have different data type and columns, so I think it is not possible to have 1 common SSIS for all of them.

We are storing our packages under the FileSystem on the server and executing them via jobs. So my question is if we make the changes in the package in BIDS(our Solution file) will it be reflected in the job or we'll have to import the package in File System?

|||

Paarul wrote:

All the source tables have different data type and columns, so I think it is not possible to have 1 common SSIS for all of them.

We are storing our packages under the FileSystem on the server and executing them via jobs. So my question is if we make the changes in the package in BIDS(our Solution file) will it be reflected in the job or we'll have to import the package in File System?

If you edit the package that's being referenced in the job, then the changes will be picked up on the next iteration.

Friday, March 9, 2012

Dynamically Choose Database

I have to write a large data migration script to move data from one SQL Server database to another. Is there any way to dynamically specify the server and database name? I would like to do something like the following, (but this does not seem to work):

Delete From [@.ServerName].[@.ImportToDatabase].[MyTable]

Any help appreciatedno. you can't do that.

EXECUTE 'DELETE FROM [' + @.ServerName + '].[' + @.ImportToDatabase + '].[username].[MyTable]'|||For some reason this doesn't seem to work in my code. However using:

EXEC ('DELETE FROM [' + @.ServerName + '].[' + @.ImportToDatabase + '].[username].[MyTable]' )

Does work.

Thanks for your comments

dynamically changing or concatenating the where statment in a

no that wont work as I would have to write protentually hundreds of differen
t
queries to handle different conbinations of the query
"Uri Dimant" wrote:

> Based on your narrative I can suggest something like that
> create proc myproc
> @.x int,
> @.y int,
> @.op int -- 1 for AND, 2 for OR
> as
> if op=1
> begin
> select * from table
> where x=coalesce(@.x,x) and y=coalesce(@.y,y)
> end
> if op=2
> begin
> select * from table
> where x=coalesce(@.x,x) or y=coalesce(@.y,y)
> end
>
> "Marcel" <Marcel@.discussions.microsoft.com> wrote in message
> news:61386D81-280C-425D-9C99-3E9170ECF8F0@.microsoft.com...
>
>Marcel
http://www.sommarskog.se/dyn-search.html
"Marcel" <Marcel@.discussions.microsoft.com> wrote in message
news:5812BA18-16D8-4DA2-9621-7B1E1001FDDE@.microsoft.com...
> no that wont work as I would have to write protentually hundreds of
> different
> queries to handle different conbinations of the query
> "Uri Dimant" wrote:
>|||Marcel (Marcel@.discussions.microsoft.com) writes:
> no that wont work as I would have to write protentually hundreds of
> different queries to handle different conbinations of the query
If the purpose is to provide a generic search routine, then read the
article that Uri posted a link to. Being the author, I like to think
that's a good article.
If the purpose is something else, consider writing several stored
procedures. The norm for stored procedures is that they are static,
and address a certain problem.
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se
Books Online for SQL Server 2005 at
http://www.microsoft.com/technet/pr...oads/books.mspx
Books Online for SQL Server 2000 at
http://www.microsoft.com/sql/prodin...ions/books.mspx

Wednesday, March 7, 2012

Dynamic where clause

I am trying to write a stored procedure usp_select using dynamic sql to select from a table. The stored procedure will accept the where clause and/or the where clause parameters. I have tried 3 different methods -

Method 1 -

exec usp_select @.whereCondition='col1 like ''abc%'' and col2 = ''xyz'''

In usp_select, I'll build and execute the sql like -

set @.sql = N'select * from table ' + @.whereConition

exec sp_executesql @.sql

(basically @.sql becomes - select * from table where col1 like 'abc%' and col2 = 'xyz')

Method 2 -

exec usp_select @.whereCondition='col1 like @.p1 and col2 = @.p2', @.WhereParams='@.p1=abc%,@.p2=xyz'

In usp_select, I'll parse out the values in @.WhereParams and then build and execute the sql like -

set @.sql = N'declare @.p1 nvarchar(10),

@.p2 nvarchar(10);

set @.p1 = ''' + @.parsedValue1 + ''', @.p2 = ''' + @.parsedValue2 + '''; ' +

N'select col1 from table1 ' + @.whereCondition

exec (@.sql)

(basically @.sql becomes - declare @.p1 nvarchar(10), @.p2 nvarchar(10);

set @.pt = 'abc%', @.p2 = 'xyz';

select col1 from table1 where col1 like @.p1 and col2 = @.p2)

Method 3 -

similar to Method 2 but exec(@.sql) will be structured to become -

exec(declare @.vparam nvarchar(100), @.p1 nvarchar(10), @.p2 nvarchar(10);

set @.vparam='@.p1 nvarchar(10), @.p2 nvarchar(10)'

set @.p1 = 'abc%', @.p2 = 'xyz';

execute sp_executesql N''select col1 from table1 where col1 like @.p1 and col2 = @.p2', @.vparam, @.p, @.p2)

When I run sql profiler on the 3 methods, method 1 and 2 always result in a Cache Miss on the entire sql structure.

On method 3, a Cache Miss always occurs on the first part of the sql, ie, the first 3 lines where I declare and set the variables. Then a Cache Hit will happen on the execute sp_executesql part.

Do I have any performance gain using method 3 with both a Cache Miss and a Cache Hit?

I hope this is not too confusing. Because I do not know the where condition to the select procedure and hardcoding the values as in method 1 always results in a Cache Miss, therefore, I come up with the ideas in Method 2 and 3.

Any advice would be appreciated.

Yes. The Method-3 is recommanded to use.

The BOL says,

Because the actual text of the Transact-SQL statement in the sp_executesql string does not change between executions, the query optimizer will probably match the Transact-SQL statement in the second execution with the execution plan generated for the first execution. Therefore, SQL Server does not have to compile the second statement.

|||

What I don't understand is in Method2, the select part of @.sql is also static with parameters, why does it still result in a cache miss?

Why does sql profiler treat the entire @.sql string in Method2 as one sql statement but in Method3, it seems to treat it as two and result in both a cache miss and a cache hit? I am building @.sql the same way in both Method 2 and 3, the only difference is method 3 uses sp_executesql and the method 2 does not.

|||

LK,

1 - The optimizer could choose to not put the plan in cache, if it is sheap enough to compile it every time. Add event "SP:CacheInsert" to see if it is adding it.

2 - Even if it adds it, the batch is using variables in the expression on the "where" clause, so the query optimizer will not use the histogram (in case you have proper indexes for c1 and c2) from the index statistics to estimate cardinality, instead it will use the value of "All Density" associate with the group of columns. While using method 3, will use the histogram properly.

Statistics Used by the Query Optimizer in Microsoft SQL Server 2005

http://www.microsoft.com/technet/prodtechnol/sql/2005/qrystats.mspx

Batch Compilation, Recompilation, and Plan Caching Issues in SQL Server 2005

http://www.microsoft.com/technet/prodtechnol/sql/2005/recomp.mspx

AMB

|||

Thank you. The articles are quite helpful too.

Sunday, February 19, 2012

Dynamic SQL String

I need to write a SQL String to retrieve a field value from a table. The problem is that I need to supply the table name as a parameter. If I was just updating a table, I could build a dynamic SQL String and use Exec()

This is what I would write if the name of the table was known:

Select @.RecordNo = MAx([VehicleID]) from Alto

This is what my dynamic SQl string looks like:

Select @.SqlStatement = 'Select Max([VehicleID]) from ' + @.TableName

So how do I run this statement and get the value it would return? Is there an equivalent to exec() that returns a value?look at
sp_execute|||Thanks for the reply.

Do you mean sp_executesql?

I can't see that I can get a value returned by using this|||Let me rephrase that...

I can't see how I can return a value into a local variable by using sp_executesql|||This doesn't generate any errors, but doesn't assign @.recordNo with a value. Am I anywhere close with this?

Select @.SqlStatement='Select Max([VehicleID]) From ' + @.TableName
exec @.RecordNo = sp_executesql @.Sqlstatement|||try this :


declare @.tbl as nvarchar(20),@.stmt as nvarchar(100)
declare @.maxid int
set @.tbl='users'
select @.stmt='select max(userid) from ' + @.tbl
exec @.maxid=sp_Executesql @.stmt
print @.maxid

hth|||oops yes sorry I dropped the sql bit!|||You have used different variable names, but apart from that I am doing exectly the same as you. Should this work?|||yes i just tried it on my tables...so you should change the table names and column names...it works for me.

hth|||Yes I agree that a value gets printed. But it doesn't come from the last line in your example. It comes from the execution of the exec statement.

I also get a value printed but the variable assignment doesn't take place. No matter what I try, I get get the assignment to happen.|||are you trying to get the id into asp.net ? you can always get the id like this :


dim MySQL as string = "select max(userid) from " & tbl
...
intid=cms.executescalar()
...

and send the tablename dynamically
and send in the table name...though its not completelyt safe...i cant think of anything else...

hth|||No i'm not trying ti get the Id into asp.net, well not directly. When the user creates a new record, I need to give it a RecordNo so it can be referenced later. So all i'm trying to do here is find the last record in the table and add 1 to it. The trouble is that the same sp will be used to work with several tables. So I need to construct this dynamic Sql string.|||you can do a select max(userid) from the table but that will not always be accurate...you can get an id of 35 ( for xample) but if some other user just made an insert while you are querying for the maxid...you can get the new id after the insert...using SCOPE_IDENTITY() function..

hth|||We seem to be losing the point here. I have no problem querying the table if the table name is fixed.

I need to be able to specify the table name in a parameter supplied to the sp. This is where I am stuck.|||I've been stuck on this problem for a week now. I need to get it sorted out. I've put the offending code into a sp of it's own. Here it is:

CREATE PROCEDURE GetNextRecordNo

@.TableName nvarchar(15)
AS

declare @.SqlStatement nvarchar(100)
declare @.RecordNo int

Select @.sqlstatement = 'Select max(VehicleID) from ' + @.TableName

execute @.RecordNo = sp_executesql @.sqlstatement

If @.RecordNo = Null select @.RecordNo = 0

select @.RecordNo=@.RecordNo+1

Return (@.RecordNo)
GO

From my main sp I am calling the above sp like this:

execute @.recordNo=GetNextRecordNo 'Alto'

If the table in question has a maximum Vehicle ID of 10 then the value returned is also 10. The only explanation for this is that the Execute command half way down the sp is what is actually returning the value.

What am I doing wrong?

Friday, February 17, 2012

Dynamic SQL Question

Hey all,I am trying to write a query against Teradata using a dynamic SQL Statement. Here's what I got:Sub Process(ByVal senderAs Object,ByVal eAs EventArgs)
Dim testAs New TextBox

Dim strSQLAs System.Text.StringBuilder =New StringBuilder("SELECT TELEPHONE, BUSINESS_NAME, TRADESTYLE, SECOND_TRADESTYLE, PHYSICAL_STREET_ADDRES, SECOND_STREET_ADDRESS, PHYSICAL_CITY, PHYSICAL_STATE, MAIL_ADDRESS, MAIL_ADDRESS_2, MAIL_CITY, MAIL_STATE, DUNS_NUMBER , PARENT_DUNS_NUMBER, HEADQUARTERS_DUNS_NUMB, GLOBAL_ULT_DUNS_NUMBER, DOMESTIC_ULT_DUNS_NUMB, PARENT_HQ_NAME, GLOBAL_ULT_BUSINESS_NA, DOMESTIC_ULT_BUSINESS_, FAMILY_UPDATE_DATE FROM VLBS_ECV.DNB_CORE")

If Len(NAME.Text) > 0Then
strSQL.AppendFormat(" WHERE BUSINESS_NAME LIKE'{0}%'", NAME.Text)
End If

If Len(Address.Text) > 0 Then
strSQL.AppendFormat(" {1} PHYSICAL_STREET_ADDRES LIKE'{0}%'", Address.Text, (strSQL.ToString().Contains("WHERE")) & " AND " & "WHERE")

End If


Dim strSQL1As String = strSQL.ToString()
test.Text = strSQL1
Dim connStrAs String ="Dsn=Connection Data"
Dim DBConnectionAs OdbcConnection =New OdbcConnection(connStr)
Dim dsAs New DataSet

Dim tblAdapterAs New OdbcDataAdapter(strSQL1, connStr)
tblAdapter.Fill(ds)
'Assign the datagrid's datasource to the datatable
SearchResults.DataSource = ds
SearchResults.DataBind()
End Sub If I put the name in, I get the query to work. But if I add another line, this is what is getting passed over:"SELECT TELEPHONE, BUSINESS_NAME, TRADESTYLE, SECOND_TRADESTYLE, PHYSICAL_STREET_ADDRES, SECOND_STREET_ADDRESS, PHYSICAL_CITY, PHYSICAL_STATE, MAIL_ADDRESS, MAIL_ADDRESS_2, MAIL_CITY, MAIL_STATE, DUNS_NUMBER , PARENT_DUNS_NUMBER, HEADQUARTERS_DUNS_NUMB, GLOBAL_ULT_DUNS_NUMBER, DOMESTIC_ULT_DUNS_NUMB, PARENT_HQ_NAME, GLOBAL_ULT_BUSINESS_NA, DOMESTIC_ULT_BUSINESS_, FAMILY_UPDATE_DATE FROM VLBS_ECV.DNB_CORE WHERE BUSINESS_NAME LIKE 'california%'True AND WHERE PHYSICAL_STREET_ADDRES LIKE '12345%'"ThatTRUE clause is causing my query to blow up. Anybody have ideas why that is doing this?

Why are you using dynamic SQL anyway? A stored procedure would be much more appropriate, even if it's just to protect your application from SQL Injection.

|||

Because I don't have access in the Warehouse to write stored procs. I have select only. Also, I'm putting some validators on the page to prevent malicious code.

|||

In that case you may be stuck but I'd try to get access if you can otherwise you could leave yourself open to attack, and it may also affect the performance of your query.

As for why you are getting the error, theContainsmethod returns a boolean value based on whether the string exists or not.

|||

Why are you checking the length of the input fields? If the length is 0, LIKE '%' will return true...

cm1jm1:

Because I don't have access in the Warehouse to write stored procs. I have select only. Also, I'm putting some validators on the page to prevent malicious code.

This doesn't mean that u should make an SQL string like this. U should use aparameterized query instead, something like:

"SELECT ... FROM VLBS_ECV.DNB_CORE WHERE BUSINESS_NAME LIKE @.name AND PHYSICAL_STREET_ADDRES LIKE @.address"

Create a command object, set this string as the commandText property, add 2 parameter objects (Values name.Text + "%" AND Address.Text + "%") and thats it

|||

Are some of the address columns really spelled ADDRES and other spelled ADDRESS?

|||

I think you are trying achieve something like below, I've modified your code:

Sub Process(ByVal senderAs Object,ByVal eAs EventArgs)Dim testAs New TextBoxDim strSQLAs System.Text.StringBuilder =New StringBuilder("SELECT TELEPHONE, BUSINESS_NAME, TRADESTYLE, SECOND_TRADESTYLE, PHYSICAL_STREET_ADDRES, SECOND_STREET_ADDRESS, PHYSICAL_CITY, PHYSICAL_STATE, MAIL_ADDRESS, MAIL_ADDRESS_2, MAIL_CITY, MAIL_STATE, DUNS_NUMBER , PARENT_DUNS_NUMBER, HEADQUARTERS_DUNS_NUMB, GLOBAL_ULT_DUNS_NUMBER, DOMESTIC_ULT_DUNS_NUMB, PARENT_HQ_NAME, GLOBAL_ULT_BUSINESS_NA, DOMESTIC_ULT_BUSINESS_, FAMILY_UPDATE_DATE FROM VLBS_ECV.DNB_CORE where 1=1")If Len(NAME.Text) > 0Then strSQL.AppendFormat(" and BUSINESS_NAME LIKE'{0}%'", NAME.Text) End If If Len(Address.Text) > 0 Then strSQL.AppendFormat(" and PHYSICAL_STREET_ADDRES LIKE'{0}%'", Address.Text)End If Dim strSQL1As String = strSQL.ToString() test.Text = strSQL1Dim connStrAs String ="Dsn=Connection Data"Dim DBConnectionAs OdbcConnection =New OdbcConnection(connStr)Dim dsAs New DataSetDim tblAdapterAs New OdbcDataAdapter(strSQL1, connStr) tblAdapter.Fill(ds)'Assign the datagrid's datasource to the datatable SearchResults.DataSource = ds SearchResults.DataBind()End Sub

I've changed the way your query is being generated. See the Where 1=1 in your basic query. Then you can just go on to add the clauses with " and ".

Hope this will help.

Wednesday, February 15, 2012

Dynamic SQL in SSIS

Hi All,
I am new to SSIS. I want to be able to write a dynamic SQL statement for a Data Flow task. It would go something like this. I want to schedule an SSIS package to run everynight and extract data from an ODBC source and collect the previous day's sales info based on a date parameter, so the date parameter of the query would have to get a value based on the previous day's date
EX: SELECT * FROM Sales WHERE Invoice_Date = <previous day's date>
So far I am looking at a Script Component to do this and populate the Data Source, but I just wanted to check and make sure there isn't a better or more efficient way.

The previous day could be a simple getdate()-1 in your query however assuming you need something more complex, use the following type of things.
1) Create a variable, i.e. Qtr, String
2) Create a execute sql task or a script task to set the variable value. i.e. for SQL task something like, select cast(c.Current_Qrtr_yyyyqq as nchar(6)) as Qtr from dbo.Constants c with(nolock) and use the result set to pass the value to the variable Result set = Qtr, Variable name = User::Qtr
3) Edit the DataFlow task property, Add an expression for the SQL Command, something like your SQL between double quotes with the variable where you need it, i.e. "SELECT cast(Sum( Case when DECODE ( SIGN( NVL(B.RSD_DT,B.MSD_DT) - (Sysdate-1)), -1, 0,
Decode(B.RSD_YYYYQQ_NUM,0,B.MSD_YYYYQQ_Num, B.RSD_YYYYQQ_Num) ) = " + @.[User::Qtr] +"
then B.NET_AMT else 0 end) as varchar(50)) Current_Qtr_Net_Amt from dataware.mytable B"

Remember that you have to generate all the column mappings before implementing the expression. Also, when you build the package, the original query in the data flow get stripped out of the hard coded values that your expressions replaces, so if you want to change your metadata, you have to manually put back the values in the dataflow source item.

Hope it helps,
Philippe

|||Using dynamic SQL in an OLE DB Source component - http://blogs.conchango.com/jamiethomson/archive/2005/12/09/2480.aspx

-Jamie

dynamic sql doesnt work?

I use dynamic sql to write the following PL/SQL block, but it always states that i got error on the part for opening cursor.
Actually I dunno why there's such an error.
Please help
==============================================
DECLARE
vMap_Old_Rank char(10);
vCor_New_Rank char(10);
vTable_Name Source.table_name%TYPE;
vSQLstr varchar(9999);
this_rank rank_Mapping.old_rank%TYPE;

Cursor tableCursor IS
SELECT table_name
FROM Source;

Type cur_typ is REF CURSOR;
c cur_typ;

BEGIN
OPEN tableCursor;
LOOP
FETCH tableCursor INTO vTable_Name;
EXIT WHEN tableCursor%NOTFOUND;

OPEN rankCursor FOR 'SELECT DISTINCT(rank) FROM ' || vTable_Name;

LOOP
FETCH rankCursor INTO vMap_Old_Rank;
EXIT WHEN rankCursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(vMap_Old_Rank);

/* UPDATE vTable_Name
SET rank = vCor_New_Rank
WHERE rank = vMap_Old_Rank;
*/

END LOOP;
IF rankCursor%ISOPEN THEN CLOSE rankCursor;
END IF;

END LOOP;
IF tableCursor%ISOPEN THEN CLOSE tableCursor;
END IF;

EXCEPTION

WHEN OTHERS THEN
dbms_output.put_line('no actions!');
IF rankCursor%ISOPEN THEN CLOSE rankCursor;
END IF;
IF tableCursor%ISOPEN THEN CLOSE tableCursor;
END IF;

END;
==============================================
ERROR at line 17:
ORA-06550: line 17, column 23:
PLS-00103: Encountered the symbol "SELECT DISTINCT(rank) FROM " when expecting
one of the following:
select
==============================================I believe it has to do with this syntax and it will not work:
OPEN rankCursor FOR 'SELECT DISTINCT(rank) FROM ' || vTable_Name;

You may not be able to specify a dynamic SQL build in an OPEN. The OPEN needs to be OPEN rankCursor FOR SELECT DISTINCT(rank) FROM tbl;

Originally posted by wakuku
I use dynamic sql to write the following PL/SQL block, but it always states that i got error on the part for opening cursor.
Actually I dunno why there's such an error.
Please help
==============================================
DECLARE
vMap_Old_Rank char(10);
vCor_New_Rank char(10);
vTable_Name Source.table_name%TYPE;
vSQLstr varchar(9999);
this_rank rank_Mapping.old_rank%TYPE;

Cursor tableCursor IS
SELECT table_name
FROM Source;

Type cur_typ is REF CURSOR;
c cur_typ;

BEGIN
OPEN tableCursor;
LOOP
FETCH tableCursor INTO vTable_Name;
EXIT WHEN tableCursor%NOTFOUND;

OPEN rankCursor FOR 'SELECT DISTINCT(rank) FROM ' || vTable_Name;

LOOP
FETCH rankCursor INTO vMap_Old_Rank;
EXIT WHEN rankCursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(vMap_Old_Rank);

/* UPDATE vTable_Name
SET rank = vCor_New_Rank
WHERE rank = vMap_Old_Rank;
*/

END LOOP;
IF rankCursor%ISOPEN THEN CLOSE rankCursor;
END IF;

END LOOP;
IF tableCursor%ISOPEN THEN CLOSE tableCursor;
END IF;

EXCEPTION

WHEN OTHERS THEN
dbms_output.put_line('no actions!');
IF rankCursor%ISOPEN THEN CLOSE rankCursor;
END IF;
IF tableCursor%ISOPEN THEN CLOSE tableCursor;
END IF;

END;
==============================================
ERROR at line 17:
ORA-06550: line 17, column 23:
PLS-00103: Encountered the symbol "SELECT DISTINCT(rank) FROM " when expecting
one of the following:
select
==============================================|||Originally posted by dmmac
I believe it has to do with this syntax and it will not work:
OPEN rankCursor FOR 'SELECT DISTINCT(rank) FROM ' || vTable_Name;

You may not be able to specify a dynamic SQL build in an OPEN. The OPEN needs to be OPEN rankCursor FOR SELECT DISTINCT(rank) FROM tbl;

YOU sulrely are able to specify dynamic sql in an open, look at following example:

SQL>var vcsr refcursor;
SQL>declare
2 tabname varchar2(32):='tables';
3 cols varchar2(128):='table_name,initial_extent,next_ext ent';
4 begin
5 open :vcsr for 'select '||cols
6 ||' from user_'||tabname
7 ||' where rownum <6';
8 end;
9 /

PL/SQL procedure successfully completed.

SQL>print :vcsr

TABLE_NAME INITIAL_EXTENT NEXT_EXTENT
---------- ----- ----
AEEMAIL 204800 204800
AETABLE 204800 204800
APPLICATION_CONTROL 5242880 1048576
CHAINED_ROWS 1081344 2129920
CHURNSTEP2 204800 204800

5 rows selected.

SQL>

Also, I do not see 'rankCursor' defined as a ref cursor anywhere!!

:cool:|||Sorry to post the wrong code before.

But in my coding, I did define rankCursor before as follows:
==============================================
DECLARE
vMap_Old_Rank char(10);
vCor_New_Rank char(10);
vTable_Name Source.table_name%TYPE;
vSQLstr varchar(9999);
this_rank rank_Mapping.old_rank%TYPE;

Cursor tableCursor IS
SELECT table_name
FROM Source;

Type cur_typ is REF CURSOR;
rankCursor cur_typ;

BEGIN
OPEN tableCursor;
LOOP
FETCH tableCursor INTO vTable_Name;
EXIT WHEN tableCursor%NOTFOUND;

OPEN rankCursor FOR 'SELECT DISTINCT(rank) FROM ' || vTable_Name;

LOOP
FETCH rankCursor INTO vMap_Old_Rank;
EXIT WHEN rankCursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(vMap_Old_Rank);

/* UPDATE vTable_Name
SET rank = vCor_New_Rank
WHERE rank = vMap_Old_Rank;
*/

END LOOP;
IF rankCursor%ISOPEN THEN CLOSE rankCursor;
END IF;

END LOOP;
IF tableCursor%ISOPEN THEN CLOSE tableCursor;
END IF;

EXCEPTION

WHEN OTHERS THEN
dbms_output.put_line('no actions!');
IF rankCursor%ISOPEN THEN CLOSE rankCursor;
END IF;
IF tableCursor%ISOPEN THEN CLOSE tableCursor;
END IF;

END;
==============================================
But the same errors still occurred.

ERROR at line 17:
ORA-06550: line 17, column 23:
PLS-00103: Encountered the symbol "SELECT DISTINCT(rank) FROM " when expecting
one of the following:
select
==============================================

I've tried LKBrwn_DBA's example. But it stated an error, "Bind variable not declared".|||Which version of Oracle are you using?

Did you try this example?:

SQL>var vcsr refcursor;

SQL>declare
2 tabname varchar2(32):='tables';
3 cols varchar2(128):= 'table_name,initial_extent,next_extent';
4 begin
5 open :vcsr for 'select '||cols
6 ||' from user_'||tabname
7 ||' where rownum <6';
8 end;
9 /|||Originally posted by LKBrwn_DBA
Which version of Oracle are you using?

Did you try this example?:

SQL>var vcsr refcursor;

SQL>declare
2 tabname varchar2(32):='tables';
3 cols varchar2(128):= 'table_name,initial_extent,next_extent';
4 begin
5 open :vcsr for 'select '||cols
6 ||' from user_'||tabname
7 ||' where rownum <6';
8 end;
9 /

I've tried, but failed again...saying
"Bind variable vscr not declared"

The one i'm using is Orcale8 Enterprise Edition Release 8.0.6.3.0|||Originally posted by wakuku
Sorry to post the wrong code before.

But in my coding, I did define rankCursor before as follows:
==============================================
DECLARE
vMap_Old_Rank char(10);
vCor_New_Rank char(10);
vTable_Name Source.table_name%TYPE;
vSQLstr varchar(9999);
this_rank rank_Mapping.old_rank%TYPE;

Cursor tableCursor IS
SELECT table_name
FROM Source;

Type cur_typ is REF CURSOR;
rankCursor cur_typ;

BEGIN
OPEN tableCursor;
LOOP
FETCH tableCursor INTO vTable_Name;
EXIT WHEN tableCursor%NOTFOUND;

OPEN rankCursor FOR 'SELECT DISTINCT(rank) FROM ' || vTable_Name;

LOOP
FETCH rankCursor INTO vMap_Old_Rank;
EXIT WHEN rankCursor%NOTFOUND;

DBMS_OUTPUT.PUT_LINE(vMap_Old_Rank);

/* UPDATE vTable_Name
SET rank = vCor_New_Rank
WHERE rank = vMap_Old_Rank;
*/

END LOOP;
IF rankCursor%ISOPEN THEN CLOSE rankCursor;
END IF;

END LOOP;
IF tableCursor%ISOPEN THEN CLOSE tableCursor;
END IF;

EXCEPTION

WHEN OTHERS THEN
dbms_output.put_line('no actions!');
IF rankCursor%ISOPEN THEN CLOSE rankCursor;
END IF;
IF tableCursor%ISOPEN THEN CLOSE tableCursor;
END IF;

END;
==============================================
But the same errors still occurred.

ERROR at line 17:
ORA-06550: line 17, column 23:
PLS-00103: Encountered the symbol "SELECT DISTINCT(rank) FROM " when expecting
one of the following:
select
==============================================

I've tried LKBrwn_DBA's example. But it stated an error, "Bind variable not declared".
Your error suggests that you used double quotes (") not single quotes (') in your example:

SQL> declare
2 type rc is ref cursor;
3 r rc;
4 begin
5 open r for "select * from dept";
6* end;
SQL> /
declare
*
ERROR at line 1:
ORA-06550: line 5, column 14:
PLS-00201: identifier 'select * from dept' must be declared
ORA-06550: line 5, column 3:
PL/SQL: Statement ignored

SQL> declare
2 type rc is ref cursor;
3 r rc;
4 begin
5 open r for 'select * from dept';
6* end;
SQL> /

PL/SQL procedure successfully completed.|||Originally posted by andrewst
Your error suggests that you used double quotes (") not single quotes (') in your example:

SQL> declare
2 type rc is ref cursor;
3 r rc;
4 begin
5 open r for "select * from dept";
6* end;
SQL> /
declare
*
ERROR at line 1:
ORA-06550: line 5, column 14:
PLS-00201: identifier 'select * from dept' must be declared
ORA-06550: line 5, column 3:
PL/SQL: Statement ignored

SQL> declare
2 type rc is ref cursor;
3 r rc;
4 begin
5 open r for 'select * from dept';
6* end;
SQL> /

PL/SQL procedure successfully completed.

I've tried this, but failed again.

It seems that "OPEN sqlstatement FOR cursor" can't be run in the SQL I'm using.

I've used other method, but it works. Here's my coding...
==============================================
DECLARE
vMap_Old_Rank char(10);
vCor_New_Rank char(10);
vTable_Name Source_Table.table_name%TYPE;
vSQLstr varchar(9999);
vTotal_Rank Integer;

TYPE cur_typ is REF CURSOR;

Cursor tableCursor IS
SELECT table_name FROM Source_Table;

rankCursor integer;
exeCursor integer;
updateCursor integer;

BEGIN
OPEN tableCursor;

LOOP

FETCH tableCursor INTO vTable_Name;
EXIT WHEN tableCursor%NOTFOUND;

rankCursor := DBMS_SQL.OPEN_CURSOR;

DBMS_SQL.PARSE(rankCursor, 'SELECT rank, new_rank, count(rank) FROM rank_Mapping, '
|| vTable_Name || ' WHERE ltrim(rtrim(rank)) = ltrim(rtrim(old_rank))
GROUP BY rank, new_rank', DBMS_SQL.NATIVE);

DBMS_SQL.DEFINE_COLUMN(rankCursor, 1, vMap_Old_Rank, 10);
DBMS_SQL.DEFINE_COLUMN(rankCursor, 2, vCor_New_Rank, 10);
DBMS_SQL.DEFINE_COLUMN(rankCursor, 3, vTotal_Rank);

exeCursor := DBMS_SQL.EXECUTE(rankCursor);

updateCursor := DBMS_SQL.OPEN_CURSOR;

LOOP

IF DBMS_SQL.FETCH_ROWS(rankCursor) > 0 THEN

DBMS_SQL.COLUMN_VALUE(rankCursor, 1, vMap_Old_Rank);
DBMS_SQL.COLUMN_VALUE(rankCursor, 2, vCor_New_Rank);
DBMS_SQL.COLUMN_VALUE(rankCursor, 3, vTotal_Rank);

DBMS_OUTPUT.PUT_LINE(vTable_Name || ' ' || vMap_Old_Rank ||'-'||
vCor_New_Rank || ': ' || vTotal_Rank);

DBMS_SQL.PARSE(updateCursor, 'UPDATE ' || vTable_Name ||
' SET rank = :vCor_New_Rank WHERE rank = :vMap_Old_Rank',
DBMS_SQL.NATIVE);

DBMS_SQL.BIND_VARIABLE(updateCursor, 'vMap_Old_Rank', vMap_Old_Rank);
DBMS_SQL.BIND_VARIABLE(updateCursor, 'vCor_New_Rank', vCor_New_Rank);

/* exeCursor := DBMS_SQL.EXECUTE(updateCursor); */

ELSE
EXIT;
END IF;

END LOOP;
IF DBMS_SQL.IS_OPEN(rankCursor) THEN
DBMS_SQL.CLOSE_CURSOR(rankCursor);
END IF;

IF DBMS_SQL.IS_OPEN(updateCursor) THEN
DBMS_SQL.CLOSE_CURSOR(updateCursor);
END IF;

END LOOP;
IF tableCursor%ISOPEN THEN CLOSE tableCursor;
END IF;

EXCEPTION

..............

END;
==============================================|||but it doesnt work if the ref cursor is declared with a return value.
for example, following would work
--------------
CREATE OR REPLACE
PACKAGE rcpackage IS

TYPE Recx IS RECORD
(a VARCHAR2(100));

TYPE MODULESCurType IS REF CURSOR ;

function x return rcPackage.MODULESCurType ;

END;
/

CREATE OR REPLACE
PACKAGE BODY rcpackage IS

function x return rcPackage.MODULESCurType is

t rcPackage.MODULESCurType;
s varchar2(500);

begin

s :='select * from tab';

open T for s;

return t;
end;

END;
/
----------

but not following
-----------
-- Start of DDL Script for Package RECON.RCPACKAGE
-- Generated 2-Oct-2003 22:33:06 from RECON@.CGEN

CREATE OR REPLACE
PACKAGE rcpackage IS

TYPE Recx IS RECORD
(a VARCHAR2(100));

TYPE MODULESCurType IS REF CURSOR return Recx ;

function x return rcPackage.MODULESCurType ;

END;
/

CREATE OR REPLACE
PACKAGE BODY rcpackage IS

function x return rcPackage.MODULESCurType is

t rcPackage.MODULESCurType;
s varchar2(500);

begin

s :='select * from tab';

open T for s;

return t;

end;

END;
/
-----------

Originally posted by LKBrwn_DBA
YOU sulrely are able to specify dynamic sql in an open, look at following example:

SQL>var vcsr refcursor;
SQL>declare
2 tabname varchar2(32):='tables';
3 cols varchar2(128):='table_name,initial_extent,next_ext ent';
4 begin
5 open :vcsr for 'select '||cols
6 ||' from user_'||tabname
7 ||' where rownum <6';
8 end;
9 /

PL/SQL procedure successfully completed.

SQL>print :vcsr

TABLE_NAME INITIAL_EXTENT NEXT_EXTENT
---------- ----- ----
AEEMAIL 204800 204800
AETABLE 204800 204800
APPLICATION_CONTROL 5242880 1048576
CHAINED_ROWS 1081344 2129920
CHURNSTEP2 204800 204800

5 rows selected.

SQL>

Also, I do not see 'rankCursor' defined as a ref cursor anywhere!!

:cool:|||hi actually i really wanna help in this TASK could u please help me out as soon as possible.....i kindly thanxs for that...
----------------

There are a number of subtasks to this weekly task. PL/SQL is not necessary. It will be
sufficient to use SQL. However you will need a firm grasp of the concepts of Week 7
lectures to be able to do the subtasks.
1) Create the following table
StudentTableNotNormalised
StudId Name CourseCode CourseDesc Lecturer Grade Office
S1234 Jack C224 Database Codd D 381
S1234 Jack C225 Algorithms Djikstra P 380
S2345 Jill C224 Database Codd HD 381
S2345 Jill C226 Architecture Ritchie HD 390
S4567 Jack C226 Architecture Ritchie D 390
S4567 Jack C224 Database Codd F 381
S9872 Howard Cpol Politics Marx F 380
2) Design a schema for this table that is in second normal form but not third normal
form.
Demonstrate this schema (you can if you like use views from your original table
to demonstrate the schema and populations: Hint use Distinct, , alternatively
create the tables and populations with a script).
3) Design a schema for this that is in third normal form.
Demonstrate this schema (again you can use views, alternatively create the
tables and populations with a script)
4) Functional dependencies.
Create two SQL queries on the table StudentTableNotNormalised
to ascertain whether Lecturer functionally determines Office and conversely
whether Office functionally determines Lecturerer.
(Hint Use Distinct, Group by and count)

Dynamic SQL colunms into rows

Im trying to write a SQL script that will turn the rows from one table into colunms. I'm using the sp_excutesql porceure and it keeps coming back with an error.

The problem is that i cant seem to be able to use @.parameter as a name when i try to dynamically create a column. Its a dynamic sql problem but i cant seem to get around it.

This is the problem line -- SELECT @.SQL ='ALTER TABLE tblHM21 ADD @.ColName varchar(50)'

Create Table tblHM21 (uidHM21uniqueidentifier);-- loop through tests to get bring back names of the rows-- --declare @.rowCountintdeclare @.iintset @.i = 1set @.rowCount = (SELECTCount(intTestTableRow)FROM tblHSTests)while @.i <= @.rowCount
Begindeclare @.ColumnNamenvarchar(50)set @.columnName = (Select strTestNamefrom tblHStestswhere intTestTableRow = @.i)declare @.SQLnvarchar(500)declare @.paramsnvarchar(4000)SELECT @.SQL ='ALTER TABLE tblHM21 ADD @.ColName varchar(50)'SELECT @.params = N'@.ColName nvarchar(50)'EXECsp_executesql @.SQL, @.params, @.ColumnNameprint @.iprint @.ColumnNameset @.i = @.i+1Endselect *from tblHM21Drop Table tblHM21
hi

put

set@.SQL ='ALTER TABLE tblHM21 ADD @.ColName varchar(50)'
set @.params = N'@.ColName nvarchar(50)'
 
and before  execute print @.sql
no need to send parameter individually
u can add parameter within the sql statement 

|||

i tried that. I'll try agian theyere might be something i missed but i dont think so.

I have tired eveything and have figured out that it cant be done. Sanson