MSSQL 의 pivot table 을 리턴하는 프로시저를 실행하여 

해당 데이터를 화면에 뿌려주기 위한 작업.

 

dynamic 컬럼을 만드는 방법은 이전 포스팅에 있음

https://oyesji.tistory.com/60

 

Pivot 결과로 컬럼, 로우 총합 구하기

https://www.codeproject.com/Articles/232181/SQL-Pivot-with-Grand-Total-Column-and-Row SQL Dynamic Pivots Introduction Microsoft SQL Server has introduced the PIVOT and UNPIVOT commands as enhancemen..

oyesji.tistory.com

 

1. mybatis xml

resultType 주의!

<select id="selectTest" parameterType="int" resultType="java.util.LinkedHashMap">
	--selectTest
	EXEC dbo.TEST
		@IDX = #{idx}
</select>

 

2. service

dynamic 컬럼명을 별도로 추출해야함.

List< Map< String, Object > > rList = this.mapper.selectTest( idx );
Set<String> header = null;

LinkedList< Map< String, Object > > list = new LinkedList<>();
list.addAll( rList );

if ( list != null && list.size() > 0 ) {
	//컬럼명 추출
  for ( ListIterator< Map< String, Object > > it = (ListIterator< Map< String, Object > >) list.iterator(); it.hasNext(); ) {
    Map< String, Object > column = it.next();
    if( NumberUtils.toInt( Objects.toString( column.get( "SEQ" ) ) ) == 0 ) {
    	header = column.keySet();
    }
  }
}

 

3. view

<c:forEach items="${list}" var="item" varStatus="row" >
	<tr>
		<c:forEach items="${header}" var="h" varStatus="col">
			<c:set var="headerName" value="${h}"></c:set>
			${item[headerName]}
		</c:forEach>
	</tr>
 </c:forEach>

 

'Language > JAVA' 카테고리의 다른 글

Attribute로 XML Parse 하기 (htmlTag 포함)  (0) 2017.09.12

java와 Oracle 에서의 사용법은 서치해보니 많이 나온다. 

c# 과 Mssql 의 경우도 서치하면 정보가 많다. 

DataTable 혹은 oracle.sql.ARRAY 등을 이용한 내용들..


하지만, java 와 Mssql 에서의 방법에 대해서는 없다.


그래서 찾던 중 Mssql 의 Type 활용하여 해결하였다.




먼저 사용자정의 타입을 생성해야 한다.


1.

CREATE TYPE UserDataType AS TABLE   
( 
ID Int, 
TextData varchar(255),
DateValue datetime
)


그리고 프로시저 생성시 파라미터로 위에 생성한 타입을 받는다.


2.

Create proc p_TestProc
(
@UserDataType dbo.UserDataType ReadOnly
)
as
--Select from the Table Type passed to SP
Select * from @UserDataType

GO


그런 뒤 호출한다.


3.

Declare @UserDataType dbo.UserDataType

Insert into @UserDataType
SELECT 1, 'SomeText', getdate()

Exec p_TestProc @UserDataType



Mybatis 안에서는 위 3번의 내용을 수정하면 된다.

<select id="testSelect" parameterType="map" resultType="map>

Declare @UserDataType dbo.UserDataType Insert into @UserDataType     <foreach collection="list" item="item" separator=",">

(#{item.id}, #{item.textData}, #{item.dateValue})

</foreach>


Exec p_TestProc @UserDataType

</select>



참고 : https://social.msdn.microsoft.com/Forums/SqlServer/en-US/d63bfb5f-27d6-4124-b1f3-fe2c6faf8a0a/array-as-stored-procedure-parameter?forum=transactsql

https://www.codeproject.com/Articles/232181/SQL-Pivot-with-Grand-Total-Column-and-Row

 

 

SQL Dynamic Pivots

Introduction

Microsoft SQL Server has introduced the PIVOT and UNPIVOT commands as enhancements to T-SQL with the release of Microsoft SQL Server 2005. Pivot Table in SQL has the ability to display data in custom aggregation. PIVOT rotates a table-valued expression by turning the unique values from one column in the expression into multiple columns in the output, and performs aggregations where they are required on any remaining column values that are wanted in the final output. UNPIVOT performs the opposite operation to PIVOT by rotating columns of a table-valued expression into column values.

More information on Pivot.

In this article, I’m concentrating on how to display Grand Total row and column for the pivot table as shown in the below grid view:

Here in the grid, I’m showing the number of matches played by a team in each month. At last, I need to show the grand total for each team (Last column) - this total gives the year count for the teams. In the same way, I need a grand total row as last row in grid, which will give the number of matches played by all the teams for that particular month.

Background

Usually as a .NET developer, first I will get the pivot table from the stored procedure to dataset and grand total row and column. I will manipulate in the C#/ VB code using Datatable (Datatable compute method for better performance). But in this article, I want to show how to get the grand total row and column from the stored procedure, so that we can directly display data in the grid without any manipulation in the C#/VB.

How It Works

Here I’m using pivot with dynamic columns, most questions were about the column list in the PIVOT statement. This list is fixed, but many times the new columns are determined by the report at a later stage. This problem is easily solved when we mix pivots with dynamic SQL, so here is a very simple script about how to dynamically generate the pivot statement:

DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',[' + colName + ']', '[' + colName + ']')
FROM    Table1
WHERE	Conditions
ORDER BY colName

PRINT @cols

The above script gives you the list of columns in string format with commas. Example: [Jan], [Feb], [Mar], [Apr], [May], [Jun], [Jul], [Aug], [Sept], [Oct], [Nov], [Dec]. If you pass this dynamic query to your pivot, then your pivot columns will display dynamically.
The below SQL script creates the stored procedure which returns pivot table as output.

CREATE PROCEDURE pivot_TeamVsMatches
AS

/*First get the dynamic columns query*/

DECLARE @columnHeaders NVARCHAR (MAX)
SELECT @columnHeaders  = _
	COALESCE (@columnHeaders  + ',[' + month + ']', '[' + month + ']')
FROM    tbl_Matches
ORDER BY month

DECLARE @FinalQuery NVARCHAR(MAX)

SET @FinalQuery = 	‘SELECT *
			FROM
				(SELECT Team,
					   Month
				FROM tbl_Matches
				) A
			PIVOT
				(
				 COUNT(*)
				 FOR ColName
				 IN (‘+@columnHeaders +’)
				) B
ORDER BY Team’
PRINT ‘Pivot Queuery :’+ @FinalQuery
EXECUTE (@FinalQuery)
GO

This stored procedure returns pivot table as below:

Now to get the grand total and row, we need to form the COALESCE query. As shown below…

/* GRAND TOTAL COLUMN */
DECLARE @GrandTotalCol	NVARCHAR (MAX)
SELECT @GrandTotalCol = COALESCE (@GrandTotalCol + ‘ISNULL _
([' + CAST (Month AS VARCHAR) +'],0) + ', 'ISNULL([' + CAST(Month AS VARCHAR)+ '],0) + ')
FROM	tbl_Matches
GROUP BY Month
ORDER BY  Month
SET @GrandTotalCol = LEFT (@GrandTotalCol, LEN (@GrandTotalCol)-1)

The above query returns as below…

@GrandTotalCol = ISNULL ([' + CAST (Jan AS VARCHAR) +'],0) + ISNULL _
([' + CAST (Feb AS VARCHAR) +'],0) + ISNULL ([' + CAST (March AS VARCHAR) +'],0) + _
…………. + ISNULL ([' + CAST (Dec AS VARCHAR) +'],0).

/* GRAND TOTAL ROW */
DECLARE @GrandTotalRow	NVARCHAR(MAX)
SELECT @GrandTotalRow = COALESCE(@GrandTotalRow + ',ISNULL(SUM([' + _
CAST(Month AS VARCHAR)+']),0)', 'ISNULL(SUM([' + CAST(Month AS VARCHAR)+']),0)')
FROM	tbl_Matches
GROUP BY Month
ORDER BY  Month

The above query returns as below…

@GrandTotalRow = ISNULL(SUM([' + CAST(Jan AS VARCHAR)+']),0) + _
ISNULL(SUM([' + CAST(Feb AS VARCHAR)+']),0) + ……… + _
ISNULL(SUM([' + CAST(Dec AS VARCHAR)+']),0).

The above COALESCE strings need to be used in dynamic pivot query…

Below is the stored procedure which will give the total output of our requirement.

CREATE PROCEDURE pivot_TeamVsMatches
AS
/* COLUMNS HEADERS */
DECLARE @columnHeaders NVARCHAR (MAX)
SELECT @columnHeaders  = COALESCE (@columnHeaders  _
+ ',[' + month + ']', '[' + month + ']')
FROM    tbl_Matches
GROUP BY month
ORDER BY month

/* GRAND TOTAL COLUMN */
DECLARE @GrandTotalCol	NVARCHAR (MAX)
SELECT @GrandTotalCol = COALESCE (@GrandTotalCol + ‘ISNULL ([' + _
CAST (Month AS VARCHAR) +'],0) + ', 'ISNULL([' + CAST(Month AS VARCHAR)+ '],0) + ')
FROM	tbl_Matches
GROUP BY Month
ORDER BY Month
SET @GrandTotalCol = LEFT (@GrandTotalCol, LEN (@GrandTotalCol)-1)

/* GRAND TOTAL ROW */
DECLARE @GrandTotalRow	NVARCHAR(MAX)
SELECT @GrandTotalRow = COALESCE(@GrandTotalRow + ',ISNULL(SUM([' + _
CAST(Month AS VARCHAR)+']),0)', 'ISNULL(SUM([' + CAST(Month AS VARCHAR)+']),0)')
FROM	tbl_Matches
GROUP BY Month
ORDER BY  Month

/* MAIN QUERY */
DECLARE @FinalQuery NVARCHAR (MAX)
SET @FinalQuery = 	‘SELECT *, ('+ @GrandTotalCol + ') _
AS [Grand Total] INTO #temp_MatchesTotal
			FROM
				(SELECT Team,
					   Month
				FROM tbl_Matches
				) A
			PIVOT
				(
				 COUNT (*)
				 FOR ColName
				 IN (‘+@columnHeaders +’)
				) B
ORDER BY Team
SELECT * FROM #temp_MatchesTotal UNION ALL
SELECT ''Grand Total'','''','+@GrandTotalRow +', _
ISNULL (SUM([Grand Total]),0) FROM #temp_MatchesTotal
DROP TABLE #temp_MatchesTotal'
-- PRINT 'Pivot Query '+@FinalQuery
EXECUTE(@PivotQuery)
GO

Result as below…

Here in this stored procedure, I have used a temporary table to get the grand total row. I did the UNION ALLwith temporary table; don’t forget to drop the temporary table.

For any queries & suggestions, mail me @ narapareddy.shyam@gmail.com. By using some third party controls also we can achieve this, but here I concentrated only on typical/ normal SQL query. If anybody has any efficient and different ways, kindly share with me.

Thanks again. Bye.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

 

 

 

 

 

 

 

 

 

실제 사용 예)

DECLARE @COL_HEADERS NVARCHAR(MAX); 
SELECT TOP 1 @COL_HEADERS = 
			STUFF(( 
				SELECT ',' + '[' + a.SUBJECT + ']' 
				FROM TEST a WITH(NOLOCK) 
				WHERE a.IDX = 1
				ORDER BY a.IDX
				FOR XML PATH('') 
			), 1, 1, '') 

* 환경


- Spring Framework : 4.3.2.RELEASE

- Maven : 4.0.0

- Java version : 1.8

- Tomcat version : 8.0

- Eclipse : photon 

- Git


* 문제상황

- Eclipse photon 을 새로 받아 기존 프로젝트를 옮기는 중

Tomcat 실행 시 성공.

URL 접속 시  404 발생.

..../test.jsp 는 정상


* 해결

프로젝트 > Properties > Deployment Assembly 에서

Deploy Path 확인.


[참고] http://naver.me/5sCW95hr


내 경우엔 Maven Dependencies 경로가 없어서 발생

프로젝트 > Properties > Deployment Assembly > Add.. > Java Build Path Entires > Maven Dependencies > Finish 


이걸로 해결.





아이디 마스킹

id = id.replace(/(?<=.{3})./gi, "*");    // 세자리 이후엔 * 처리



추가>

IE 에서는 위 정규식이 오류가 남.

map 과 join 을 사용하는 걸로 변경.



//id 마스킹 function maskingId(id) { var mask = id.split('').map(function(o, i){ if( i < 3 ) { return o; } else { return '*'; } }).join(''); return mask; } //name 마스킹 function maskingName(name) { name = name.substring(0, 1) + name.substring(1, 2).replace(/./g, "*") + name.substring(2, name.length); return name; }

XML 파싱

public XMLParseTest() { this.doc = null; this.xpath = null; try { URL url = new URL( XML_URL ); URLConnection connection = url.openConnection(); this.doc = parseXML( connection.getInputStream() ); this.xpath = XPathFactory.newInstance().newXPath(); } catch ( Exception e ) { } } private Document parseXML( InputStream stream ) throws Exception { DocumentBuilderFactory objDocumentBuilderFactory = null; DocumentBuilder objDocumentBuilder = null; Document doc = null; try { objDocumentBuilderFactory = DocumentBuilderFactory.newInstance(); objDocumentBuilder = objDocumentBuilderFactory.newDocumentBuilder(); doc = objDocumentBuilder.parse( stream ); } catch ( Exception ex ) { throw ex; } return doc; } public String item( String key ) { String str = ""; try { //str = StringUtils.stripToEmpty( Objects.toString( xpath.evaluate( "//*[@key='" + key + "']", doc, XPathConstants.STRING ) ) ); //str = str.replaceAll( "\t", "" ); // Node node = (Node) xpath.evaluate( "//*[@key='" + key + "']", doc, XPathConstants.NODE ); Element el = (Element) xpath.evaluate( "//*[@key='" + key + "']", doc, XPathConstants.NODE ); System.out.println( "### node : " + elementInner2String( el ) ); } catch ( Exception e ) { e.printStackTrace(); } return str; } private static String elementInner2String( Element el ) throws TransformerFactoryConfigurationError, TransformerException { final NodeList children = el.getChildNodes(); final StringBuilder sb = new StringBuilder(); for ( int i = 0; i < children.getLength(); i++ ) { final Node child = children.item( i ); sb.append( node2String( child ) ); } return sb.toString(); } private static String node2String( Node node ) throws TransformerFactoryConfigurationError, TransformerException { final Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes" ); final StringWriter writer = new StringWriter(); transformer.transform( new DOMSource( node ), new StreamResult( writer ) ); return writer.toString(); }

더 간단한 방법은 Html Tag 가 있는 부분은 <![CDATA[ ]]> 로~


'Language > JAVA' 카테고리의 다른 글

PIVOT의 dynamic 컬럼 가져오기  (0) 2020.02.05
$(document).ready(function() {
		$.extend({
		    redirectPost: function(location, args) {
				$("#frm1")
				.attr("action", location);
				
				$.each(args, function(key, value) {
					$("").attr({
						type: "hidden",
						name: key,
						value: value
					}).appendTo("#frm1");
				});
				$("#frm1").submit();
		    }
		});
});

		function aa() {
			if("${param.redirectUrl}" != '') {
				var redirect = "${param.redirectUrl}";
				if(redirect.indexOf("?") > -1) {
					var search = redirect.substring(redirect.indexOf("?") + 1, redirect.length);
					var url = redirect.substring(0, redirect.indexOf("?"));
					var params = JSON.parse('{"' + decodeURI(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g,'":"') + '"}');
				} else {
					url = redirect;
				}
				
				$.redirectPost(url, params);
			}
		}

신규 프로젝트 check out 후

톰캣 연결하여 로컬 테스트 해보려고 하니..

spring 을 물고 오지 못했다.


tomcat 은 정상 구동. index.jsp > redirect 안됨..


원인은

classpath 가 달라서?


해당 프로젝트를 개발하신 분의 환경은 NetBeans.

나의 IDE 는 Eclipse.


해결방안은

이클립스 종료 

> workscpae > 해당프로젝트 > .classpath 를 변경(정상 구동중인 파일로 복사.)

> 이클립스 재시작


정상확인.

서버 재시작이 안되서 찾아봄.


[root@EDU-APP-89 bin]# ./shutdown.sh -force

Using CATALINA_BASE:   /usr/local/tomcat

Using CATALINA_HOME:   /usr/local/tomcat

Using CATALINA_TMPDIR: /usr/local/tomcat/temp

Using JRE_HOME:        /usr/local/java

Using CLASSPATH:       /usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar

Using CATALINA_PID:    /usr/local/tomcat/bin/catalina.pid

PID file found but no matching process was found. Stop aborted.



$CATALINA_PID was set but the specified file does not exist. Is Tomcat running? Stop aborted.



자꾸만 PID 어쩌고 오류가 나서

$CATALINA_HOME/bin/catalina.pid  를 삭제하고 재시작해봐도 안됨.


아파치 재시작

service httpd restart


ps -ef | grep tomcat

ps -ef | grep java

해봐도 프로세스가 없다.


결론은

df -h 

디스크 100%....


공간이 부족해 서버를 띄울수 없었음....

'Server > Linux ' 카테고리의 다른 글

Korn Shell - .profile, HOME, PATH  (0) 2013.12.26
[스크랩] UNIX  (0) 2013.12.26
파일 확장자 전체 변경  (0) 2013.09.10
vi 에서 사용하면 편리한 기능들 ...  (0) 2013.06.25
8장. awk&sed  (0) 2013.06.25

[출처] http://www.sirini.net/grboard2/blog/view/760


..

중략..


문제는 첫글자를 한글로 쓸 때입니다.
이 때 한 번 쳇바퀴가 돌기 시작하면 글자가 연속적으로 쓰여지지 않고
이전에 쓴 글자가 지워지면서 새 글자가 써지는 식으로
절대 글이 써지지는 않으나 지금 무슨 글자를 쓰는지는 볼 수 있는
속 뒤집어지는 증상이 나타나게 됩니다.


TinyMCE 에디터로 변경할 textarea 태그 사이에, <p> 태그를 하나
넣어주시면 됩니다. 가령 이렇게요.

<textarea name="content" row="5" cols="20"><p></textarea>




추가. 해리님의 댓글을 확인해보세요!
아래 옵션을 TinyMCE 에 주게 되면 보다 깔끔한 해결이 가능합니다.
forced_root_block : false


...

략.

+ Recent posts