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

Friday, March 23, 2012

Recovering space in a heavily fragmented table

I have a large (240GB) table which contains a very large
amount of character data in text datatype columns. During
recent maintenance a good deal of this data has been
nulled to save space resulting in the table reporting
about 80GB of unused space within the allocated extents.
What is the best way to defrag this table and recover the
space?
The table has NO clustered index on it.
Thanks to anyone who thinks they can help!!!
JonathanHi Jonathan,
You can't recover empty extents that have been used by text directly in SQL
Server 2000, but you have two options to work around it:
1) you can copy the data to a new table, drop the old table and then rename
the new table with sp_rename.
2) copy the data in the text column to a new table, drop the text column
from the original table, run DBCC CLEANTABLE on the original table, recreate
the column and copy the data back in and finally drop the new table.
Jacco Schalkwijk
SQL Server MVP
"Jonathan Smith" <jonathan.smith@.moneysupermarket.com> wrote in message
news:48a301c3e40b$f77c7d90$a601280a@.phx.gbl...
quote:

> I have a large (240GB) table which contains a very large
> amount of character data in text datatype columns. During
> recent maintenance a good deal of this data has been
> nulled to save space resulting in the table reporting
> about 80GB of unused space within the allocated extents.
> What is the best way to defrag this table and recover the
> space?
> The table has NO clustered index on it.
> Thanks to anyone who thinks they can help!!!
> Jonathan
|||Ah. And I thought I was being really stupid and there
would be a simple answer. Thanks for your help. I believe
a long night may be in store for me...
Jonathan Smith
quote:

>--Original Message--
>Hi Jonathan,
>You can't recover empty extents that have been used by

text directly in SQL
quote:

>Server 2000, but you have two options to work around it:
>1) you can copy the data to a new table, drop the old

table and then rename
quote:

>the new table with sp_rename.
>2) copy the data in the text column to a new table, drop

the text column
quote:

>from the original table, run DBCC CLEANTABLE on the

original table, recreate
quote:

>the column and copy the data back in and finally drop the

new table.
quote:

>--
>Jacco Schalkwijk
>SQL Server MVP
>
>"Jonathan Smith" <jonathan.smith@.moneysupermarket.com>

wrote in message
quote:

>news:48a301c3e40b$f77c7d90$a601280a@.phx.gbl...
During[QUOTE]
the[QUOTE]
>
>.
>
|||fyi - this functional shortfall has been fixed in Yukon. Both shrink and
defrag will compact LOB extents.
Paul Randal
Dev Lead, Microsoft SQL Server Storage Engine
This posting is provided "AS IS" with no warranties, and confers no rights.
"Jonathan Smith" <jonathan.smith@.moneysupermarket.com> wrote in message
news:473d01c3e413$c7619ac0$a501280a@.phx.gbl...[QUOTE]
> Ah. And I thought I was being really stupid and there
> would be a simple answer. Thanks for your help. I believe
> a long night may be in store for me...
> Jonathan Smith
>
> text directly in SQL
> table and then rename
> the text column
> original table, recreate
> new table.
> wrote in message
> During
> the

Recovering space in a heavily fragmented table

I have a large (240GB) table which contains a very large
amount of character data in text datatype columns. During
recent maintenance a good deal of this data has been
nulled to save space resulting in the table reporting
about 80GB of unused space within the allocated extents.
What is the best way to defrag this table and recover the
space?
The table has NO clustered index on it.
Thanks to anyone who thinks they can help!!!
JonathanHi Jonathan,
You can't recover empty extents that have been used by text directly in SQL
Server 2000, but you have two options to work around it:
1) you can copy the data to a new table, drop the old table and then rename
the new table with sp_rename.
2) copy the data in the text column to a new table, drop the text column
from the original table, run DBCC CLEANTABLE on the original table, recreate
the column and copy the data back in and finally drop the new table.
--
Jacco Schalkwijk
SQL Server MVP
"Jonathan Smith" <jonathan.smith@.moneysupermarket.com> wrote in message
news:48a301c3e40b$f77c7d90$a601280a@.phx.gbl...
> I have a large (240GB) table which contains a very large
> amount of character data in text datatype columns. During
> recent maintenance a good deal of this data has been
> nulled to save space resulting in the table reporting
> about 80GB of unused space within the allocated extents.
> What is the best way to defrag this table and recover the
> space?
> The table has NO clustered index on it.
> Thanks to anyone who thinks they can help!!!
> Jonathan|||Ah. And I thought I was being really stupid and there
would be a simple answer. Thanks for your help. I believe
a long night may be in store for me...
Jonathan Smith
>--Original Message--
>Hi Jonathan,
>You can't recover empty extents that have been used by
text directly in SQL
>Server 2000, but you have two options to work around it:
>1) you can copy the data to a new table, drop the old
table and then rename
>the new table with sp_rename.
>2) copy the data in the text column to a new table, drop
the text column
>from the original table, run DBCC CLEANTABLE on the
original table, recreate
>the column and copy the data back in and finally drop the
new table.
>--
>Jacco Schalkwijk
>SQL Server MVP
>
>"Jonathan Smith" <jonathan.smith@.moneysupermarket.com>
wrote in message
>news:48a301c3e40b$f77c7d90$a601280a@.phx.gbl...
>> I have a large (240GB) table which contains a very large
>> amount of character data in text datatype columns.
During
>> recent maintenance a good deal of this data has been
>> nulled to save space resulting in the table reporting
>> about 80GB of unused space within the allocated extents.
>> What is the best way to defrag this table and recover
the
>> space?
>> The table has NO clustered index on it.
>> Thanks to anyone who thinks they can help!!!
>> Jonathan
>
>.
>|||fyi - this functional shortfall has been fixed in Yukon. Both shrink and
defrag will compact LOB extents.
--
Paul Randal
Dev Lead, Microsoft SQL Server Storage Engine
This posting is provided "AS IS" with no warranties, and confers no rights.
"Jonathan Smith" <jonathan.smith@.moneysupermarket.com> wrote in message
news:473d01c3e413$c7619ac0$a501280a@.phx.gbl...
> Ah. And I thought I was being really stupid and there
> would be a simple answer. Thanks for your help. I believe
> a long night may be in store for me...
> Jonathan Smith
> >--Original Message--
> >Hi Jonathan,
> >
> >You can't recover empty extents that have been used by
> text directly in SQL
> >Server 2000, but you have two options to work around it:
> >
> >1) you can copy the data to a new table, drop the old
> table and then rename
> >the new table with sp_rename.
> >2) copy the data in the text column to a new table, drop
> the text column
> >from the original table, run DBCC CLEANTABLE on the
> original table, recreate
> >the column and copy the data back in and finally drop the
> new table.
> >
> >--
> >Jacco Schalkwijk
> >SQL Server MVP
> >
> >
> >"Jonathan Smith" <jonathan.smith@.moneysupermarket.com>
> wrote in message
> >news:48a301c3e40b$f77c7d90$a601280a@.phx.gbl...
> >> I have a large (240GB) table which contains a very large
> >> amount of character data in text datatype columns.
> During
> >> recent maintenance a good deal of this data has been
> >> nulled to save space resulting in the table reporting
> >> about 80GB of unused space within the allocated extents.
> >> What is the best way to defrag this table and recover
> the
> >> space?
> >> The table has NO clustered index on it.
> >> Thanks to anyone who thinks they can help!!!
> >>
> >> Jonathan
> >
> >
> >.
> >sql

Wednesday, March 7, 2012

Recordset insert into a table in a SP

Hi,
I need to insert a recordset into a single columns in a table in a Stored procedure.
I have dine the following:
Insert into Staging_Table Values(Recordset)
I get an error that only constants are allowed.
How can I insert the recordset values into that table?RE:
Hi,
I need to insert a recordset into a single columns in a table in a Stored procedure. I have dine the following:
Insert into Staging_Table Values(Recordset)
I get an error that only constants are allowed.
Q1 How can I insert the recordset values into that table?

A1 Insert values inserts (explicit) values. (Try posting the applicable ddl and some sample statements if this is what you are doing.)

For Example:

Use TempDB
Go

CREATE TABLE TestTable ( column_1 varchar(32))
Go

INSERT TestTable VALUES ('Row #1 Value')
INSERT TestTable VALUES ('Row #2 Value')

SELECT * From TestTable|||How do you want to store the recordset in the column and how would you extract information from it once is has been stored in the column ? Please post your existing code.|||Originally posted by rnealejr
How do you want to store the recordset in the column and how would you extract information from it once is has been stored in the column ? Please post your existing code.

Hi,
My existing code is:

if @.col2 is null
Begin
set @.SQL = 'create table LanTable ( ' + @.col1 + ' nvarchar(60))'
exec (@.SQL)
Insert into LanTable SELECT Data1= substring ( Record_Line , @.Pos1,@.Len1) FROM Staging_Table
End
else if @.col3 is null
Begin
set @.SQL = 'create table LanTable ( ' + @.col1 + ' nvarchar(60),' + @.col2 + ' nvarchar(60))'
exec (@.SQL)
Insert into LanTable SELECT Data1= substring ( Record_Line , @.Pos1,@.Len1), Data2= substring ( Record_Line , @.Pos2,@.Len2) FROM Staging_Table
End

@.Pos1,@.Len1,@.col2... all are input parameters of the SP.
Staging_Table consists of one column (Record_Line) that contains the data (ex. 03 Bank 2222 -etc)
Data1 and Data2 are recordsets that each contain their values from the Staging_Table and i want it to be inserted into LanTable.
Can it be done?
Thanks|||Originally posted by garfild
Hi,
My existing code is:

if @.col2 is null
Begin
set @.SQL = 'create table LanTable ( ' + @.col1 + ' nvarchar(60))'
exec (@.SQL)
Insert into LanTable SELECT Data1= substring ( Record_Line , @.Pos1,@.Len1) FROM Staging_Table
End
else if @.col3 is null
Begin
set @.SQL = 'create table LanTable ( ' + @.col1 + ' nvarchar(60),' + @.col2 + ' nvarchar(60))'
exec (@.SQL)
Insert into LanTable SELECT Data1= substring ( Record_Line , @.Pos1,@.Len1), Data2= substring ( Record_Line , @.Pos2,@.Len2) FROM Staging_Table
End

@.Pos1,@.Len1,@.col2... all are input parameters of the SP.
Staging_Table consists of one column (Record_Line) that contains the data (ex. 03 Bank 2222 -etc)
Data1 and Data2 are recordsets that each contain their values from the Staging_Table and i want it to be inserted into LanTable.
Can it be done?
Thanks

Hi again,
Try to use this SP and tell me what i did wrong:

CREATE PROCEDURE Lan_BuildTable
@.col1 nvarchar(60), @.Pos1 int=null, @.Len1 int=null,@.col2 nvarchar(60) = null,@.Pos2 int = null, @.Len2 int=null
AS
declare @.SQL as varchar(3000)

if @.col2 is null
Begin
set @.SQL = 'create table LanTable ( ' + @.col1 + ' nvarchar(60))'
exec (@.SQL)
Insert into LanTable SELECT Data1= substring ( Record_Line , @.Pos1,@.Len1) FROM Staging_Table
End
else if @.col3 is null
Begin
set @.SQL = 'create table LanTable ( ' + @.col1 + ' nvarchar(60),' + @.col2 + ' nvarchar(60))'
exec (@.SQL)
Insert into LanTable SELECT Data1= substring ( Record_Line , @.Pos1,@.Len1), Data2= substring ( Record_Line , @.Pos2,@.Len2) FROM Staging_Table
End

In the VB code I used:
exec Lan_BuildTable OpCode,1,2,Product,4,5

Thanks
Yossi

Saturday, February 25, 2012

Records comparsion

Hi,

I have a table of say 5 columns containing 100 records. The records are extracted from DB2. Now records need to be fetched on a nightly basis to the table. Only those records that are new should be fetched. If the records are the same then do not fetch them. What is the simplest way of implementing this?

Thanks.You may add a column to set a flag to inducate which record is new.|||Set up a second work table that looks like the first...

You'll then have to deal with 3 potential actions,

INSERT: New records on the file
DELETES: Records that don't exists
UPDATES: Records that are on the file, but attributes have changed

Do you have a PK on the table now?|||For most cases, datetime field is a good candidate to determine a record is old or new.|||Yes I have a primary key (It's a composite key made up of 2 columns)
[]
QUOTE]Originally posted by Brett Kaiser
Set up a second work table that looks like the first...

You'll then have to deal with 3 potential actions,

INSERT: New records on the file
DELETES: Records that don't exists
UPDATES: Records that are on the file, but attributes have changed

Do you have a PK on the table now? [/QUOTE]|||You only insert records that do not already exist - Could you be more specific as to what you need ? Also, what are you using now to import the records from db2 ?|||I use ODBC driver to get records from DB2. The records have a PK and attributes. Say attribute1,2,3...5. Now I only need to call insert a record if the PK has changed OR if attribute 1 for the records has changed. If attribute 2,3,4,5 have changed, then that does not matter. I do not call that records New.|||What programming language are you using ?|||T-SQL.|||Ummm, don't you want to INSERT when the PK changes, but UPDATE when column 1 changes? Otherwise, you get relational integrity issues. This should be handled in two different steps after the data is loaded into a staging table.

blindman|||He wants this...

USE Northwind
GO

CREATE TABLE myTable99 (
Col1 char(1)
, Col2 char(1)
, Col3 char(1)
, Col4 char(1)
, Col5 char(1)
, CONSTRAINT myTable99_pk PRIMARY KEY (Col1, Col2))

CREATE TABLE myTable00 (
Col1 char(1)
, Col2 char(1)
, Col3 char(1)
, Col4 char(1)
, Col5 char(1)
, CONSTRAINT myTable00_pk PRIMARY KEY (Col1, Col2))
GO

INSERT INTO myTable99(Col1,Col2,Col3,Col4,Col5)
SELECT '1','1','a','b','c' UNION ALL
SELECT '1','2','d','e','f' UNION ALL
SELECT '1','3','g','h','i' UNION ALL
SELECT '1','4','j','k','l'
--DELETED

INSERT INTO myTable00(Col1,Col2,Col3,Col4,Col5)
SELECT '1','1','a','b','c' UNION ALL --NO CHANGE
SELECT '1','2','x','y','z' UNION ALL -- UPDATE
SELECT '1','3','g','h','i' UNION ALL --NO CHANGE
SELECT '2','3','a','b','c' --INSERT
GO

SELECT * FROM myTable99
SELECT * FROM myTable00
GO

--DO DELETES FIRST

DELETE FROM a
FROM myTable99 a
LEFT JOIN myTable00 b
ON a.Col1 = b.Col1
AND a.Col2 = b.Col2
WHERE b.Col1 IS NULL AND b.Col2 IS NULL

-- INSERT

INSERT INTO myTable99(Col1,Col2,Col3,Col4,Col5)
SELECT a.Col1, a.Col2, a.Col3, a.Col4, a.Col5
FROM myTable00 a
LEFT JOIN myTable99 b
ON a.Col1 = b.Col1
AND a.Col2 = b.Col2
WHERE b.Col1 IS NULL AND b.Col2 IS NULL

-- UPDATE

UPDATE a
SET Col3 = b.Col3
, Col4 = b.Col4
, Col5 = b.Col5
FROM myTable99 a
INNER JOIN myTable00 b
ON a.Col1 = b.Col1
AND a.Col2 = b.Col2
AND ( a.Col3 <> b.Col3
OR a.Col4 <> b.Col4
OR a.Col5 <> b.Col5)
GO

SELECT * FROM myTable99
SELECT * FROM myTable00
GO

DROP TABLE myTable00
DROP TABLE myTable99
GO|||Brett . Thanks a lot. I am getting close. But this is how I need it.

INSERT INTO myTable99(Col1,Col2,Col3,Col4,Col5)
SELECT '1','1','a','b','c' UNION ALL

INSERT INTO myTable00(Col1,Col2,Col3,Col4,Col5)
SELECT '1','1','a','d','z' UNION ALL --NO CHANGE

Col3,4,5 are attributes. If PK changes then insert new record. If for same PK, attribute 2,3 changes but attribute 1 is unchanged then do not INSERT (No change). I need a history of the records and so I do not do updates. I just insert new records.|||OK...I wouldn't do ot this way...

I wouldn't keep all the history in 1 table...I would use a trigger and a history table...

Hey, but they're the reqs...you're going to have to find the PK with the max timestamp every time for the current row..

EDIT: And what, prey tell, does the concept of "DELETE" mean anymore to this process?

USE Northwind
GO

CREATE TABLE myTable99 (
Col1 char(1)
, Col2 char(1)
, Col3 char(1)
, Col4 char(1)
, Col5 char(1)
, Col6 datetime DEFAULT GetDate()
, CONSTRAINT myTable99_pk PRIMARY KEY (Col1, Col2,col6))

CREATE TABLE myTable00 (
Col1 char(1)
, Col2 char(1)
, Col3 char(1)
, Col4 char(1)
, Col5 char(1))
GO

INSERT INTO myTable99(Col1,Col2,Col3,Col4,Col5)
SELECT '1','1','a','b','c' UNION ALL
SELECT '1','2','d','e','f' UNION ALL
SELECT '1','3','g','h','i' UNION ALL
SELECT '1','4','j','k','l'
--DELETED

INSERT INTO myTable00(Col1,Col2,Col3,Col4,Col5)
SELECT '1','1','a','b','c' UNION ALL --NO CHANGE
SELECT '1','2','x','y','z' UNION ALL -- UPDATE
SELECT '1','3','g','h','i' UNION ALL --NO CHANGE
SELECT '2','3','a','b','c' --INSERT
GO

SELECT * FROM myTable99
SELECT * FROM myTable00
GO

-- INSERT

INSERT INTO myTable99(Col1,Col2,Col3,Col4,Col5)
SELECT a.Col1, a.Col2, a.Col3, a.Col4, a.Col5
FROM myTable00 a
LEFT JOIN myTable99 b
ON a.Col1 = b.Col1
AND a.Col2 = b.Col2
WHERE b.Col1 IS NULL AND b.Col2 IS NULL

-- "UPDATE"

INSERT INTO myTable99(Col1,Col2,Col3,Col4,Col5)
SELECT b.Col1, b.Col2, b.Col3, b.Col4, b.Col5
FROM myTable99 a
INNER JOIN myTable00 b
ON a.Col1 = b.Col1
AND a.Col2 = b.Col2
AND ( a.Col3 <> b.Col3
OR a.Col4 <> b.Col4
OR a.Col5 <> b.Col5)
GO

SELECT * FROM myTable99
SELECT * FROM myTable00
GO

DROP TABLE myTable00
DROP TABLE myTable99
GO|||...and what, prey tell, does the concept of "PRIMARY KEY" mean anymore to this process?

blindman|||Hey..it got extended to include the "property" (if you will) of time...

smoke'em if you got 'em...

I still think you should go with a historical table and triggers though...If you stll need to see all of the history, just create a view...|||I understand that I need to do the Deletes first. I could do either an Insert or an Update after that,correct? There is no order for Inserts and Updates,correct?

Also can I execute this code in one stored procedure? I generally execute one query in one stored proc and then check for error condition. Here is my error condition -

SELECT @.ERRORNUM = @.@.ERROR, @.LOCALROWCOUNT = @.@.ROWCOUNT
IF @.ERRORNUM = 0
BEGIN
IF @.LOCALROWCOUNT >= 1
BEGIN
SELECT @.RETURNVALUE = 0
END
ELSE
BEGIN
SELECT @.RETURNVALUE = 0
RAISERROR ('FETCH FAILS: No row matching the specified criteria is found.',16, 1)
END
END
ELSE
BEGIN
SELECT @.RETURNVALUE = 1
END
RETURN @.RETURNVALUE

--

If I executes multiple queries, like the Delete/Insert/Update in one stored proc then how does this error condition change. Should I have the @.error checking after every query?

Records Between two date columns

Hi All,
I am having a problem getting records between two date columns. My table is shown below.

SAP_ID JoinDate LeaveDate
1 2006-01-23 00:00:00.000 2006-04-12 00:00:00.000
2 2006-09-04 00:00:00.000 2007-10-10 00:00:00.000
3 2006-10-03 00:00:00.000 2007-01-01 00:00:00.000
4 2007-12-04 00:00:00.000 2007-10-10 00:00:00.000

From asp page i am getting joindate and leavedate . I need to show records between joindate and leavedate.

For ex:
If
JoinDate=2006-01-01
LeaveDate=2007-01-01
then

report should show 1,2,3 SAP No's. But My Query showing only 1, 3. Here is the my query.

select sap_id from tblsap where joindate >= '2006-01-01' and leavedate <='2007-01-01'

I am not able to figure out the problem. Can some one please post suggestions to my problem.

Rajesh

The row 3 has leaveDate greater than 2007-01-01. You can AND logic in where clause and that row doesn't match where clause. So your query won't catch this row. You need understand requirement and make a little change your code.

SAP_ID JoinDate LeaveDate
3 2006-10-03 00:00:00.000 2007-01-01 00:00:00.000

select sap_id from tblsap where joindate >= '2006-01-01' and leavedate <='2007-01-01'

|||

As I understand the problem, you want rows where the 'active' period included any part of the year 2006.

I think that this should accomplish the task.

Code Snippet


SET NOCOUNT ON


DECLARE @.MyTable table
( SAP_ID int,
JoinDate datetime,
LeaveDate datetime
)


INSERT INTO @.MyTable VALUES ( 1,'2006-01-23', '2006-04-12' )
INSERT INTO @.MyTable VALUES ( 2,'2006-09-04', '2007-10-10' )
INSERT INTO @.MyTable VALUES ( 3,'2006-10-03', '2007-01-01' )
INSERT INTO @.MyTable VALUES ( 4,'2007-12-04', '2007-10-10' )
INSERT INTO @.MyTable VALUES ( 5,'2005-05-15', '2007-10-10' )
INSERT INTO @.MyTable VALUES ( 6,'2007-01-01', '2007-10-10' )
INSERT INTO @.MyTable VALUES ( 7,'2005-05-15', '2005-12-31' )


SELECT
Sap_ID,
JoinDate,
LeaveDate
FROM @.MyTable
WHERE ( JoinDate < '2007-01-01' --Join Prior 2007 and
AND LeaveDate >= '2006-01-01' --Leave 2006 or After
)